GG修改器破解版下载地址:https://ghb2023zs.bj.bcebos.com/d/z/p/d/dbzs?GGXGQ
大家好,今天小编为大家分享关于gg修改器的root是哪个_gg修改器root是什么意思的内容,赶快来一起来看看吧。
作者:Xuejie原文链接:https://xuejie.space/20191018introductiontockbscriptprogrammingdebugging/
事实上,CKB 脚本工作的层级要比其他智能合约低很多,因此 CKB 的调试过程就显得相当神秘。在本文中,我们将展示如何调试 CKB 脚本。你会发现,其实调试 CKB 脚本和你日常调试程序并没有太大区别。
本文建立在 ckb v0.23.0 之上。具体的,我在每个项目中使用的是如下版本的 commit:
CKB 脚本调试的第一种方案,通常适用于 C、Rust 等编程语言。也许你已经习惯了写 C 的程序,而 GDB 也是你的好搭档。你想知道是不是可以用 GDB 来调试 C 程序,答案当然是:Yes!你肯定可以通过 GDB 来调试用 C 编写的 CKB 脚本!让我来演示一下:
首先,我们还是用之前文章中用到的关于 carrot 的例子:
#include <memory.h>#include “ckb_syscalls.h”
int main(int argc, char* argv[]) {
int ret;
size_t index = 0;
uint64_t len = 0;
unsigned char buffer[6];
while (1) {
len = 6;
memset(buffer, 0, 6);
ret = ckb_load_cell_data(buffer, &len, 0, index, CKB_SOURCE_OUTPUT);
if (ret == CKB_INDEX_OUT_OF_BOUND) {
break;
}
int cmp = memcmp(buffer, “carrot”, 6);
if (cmp) {
return -1;
}
index++;
}
return 0;
}
这里我进行了两处修改:
首先我更新了这个脚本,让它可以兼容 ckb v0.23.0。在这个版本中,我们可以使用 ckbloadcell_data 来获取 cell 的数据。
我还在这段代码中加入了一个小 bug,这样我们等会儿就可以进行调试的工作流程。如果你非常熟悉 C,你可能已经注意到了,当然你没有在意到的话也完全不用担心,稍后我会解释的。
和往常一样,我们使用官方的 toolchain 来将其编译成 RISC-V 的代码:
$ ls
carrot.c
$ git clone https:///nervosnetwork/ckb-system-scripts
$ cp ckb-system-scripts/c/ckb_*.h ./
$ ls
carrot.c ckb_consts.h ckb_syscalls.h ckb-system-scripts/
$ sudo docker run –rm -it -v `pwd`:/code nervos/ckb-riscv-gnu-toolchain:bionic-20191012 bash
root@3efa454be9af:/# cd /code
root@3efa454be9af:/code# riscv64-unknown-elf-gcc carrot.c -g -o carrot
root@3efa454be9af:/code# exit
请注意,当我编译脚本的时候,我添加了 -g,以便生成调试信息,这在 GDB 中非常有用。对于实际使用的脚本,你总是希望尽量地完善它们来尽量节省存储在链上的空间。
现在,让我们将脚本部署到 CKB 上。保持 CKB 节点处于运行状态,并启动 Ruby SDK:
pry(main)> api = CKB::API.new
pry(main)> wallet = CKB::Wallet.from_hex(api, “<your private key>”)
pry(main)> wallet2 = CKB::Wallet.from_hex(api, CKB::Key.random_private_key)
pry(main)> carrot_data = File.read(“carrot”)
pry(main)> carrot_data.bytesize
=> 19296
pry(main)> carrot_tx_hash = wallet.send_capacity(wallet2.address, CKB::Utils.byte_to_shannon(20000), CKB::Utils.bin_to_hex(carrot_data), fee: 21000)
pry(main)> carrot_data_hash = CKB::Blake2b.hexdigest(carrot_data)
pry(main)> carrot_type_script = CKB::Types::Script.new(code_hash: carrot_data_hash, args: “0x”)
pry(main)> carrot_cell_dep = CKB::Types::CellDep.new(out_point: CKB::Types::OutPoint.new(tx_hash: carrot_tx_hash, index: 0))
现在链上有了 carrot 的脚本,我们可以创建一笔交易来测试这个 carrot 脚本:
pry(main)> tx = wallet.generate_tx(wallet2.address, CKB::Utils.byte_to_shannon(100), use_dep_group: false, fee: 5000)
pry(main)> tx.outputs[0].type = carrot_type_script
pry(main)> tx.cell_deps << carrot_cell_dep
pry(main)> tx.witnesses[0] = “0x”
pry(main)> tx = tx.sign(wallet.key, pute_transaction_hash(tx))
pry(main)> api.send_transaction(tx)
CKB::RPCError: jsonrpc error: {:code=>-3, :message=>”Script(ValidationFailure(-1))”}
如果你仔细检查这笔交易,你会发现在输出的 cell 中,并没有以 carrot 开头的数据。然而我们运行之后仍然是验证失败,这意味着我们的脚本一定存在 bug。先前,没什么别的办法,你可能需要返回去检查代码,希望可以找到出错的地方。但现在没有这个必要了,你可以跳过这里的交易,然后将其输入到一个独立的 CKB 调试器开始调试它!
首先,让我们将这笔交易连同使用的环境,都转存到一个本地文件中:
pry(main)> CKB::MockTransactionDumper.new(api, tx).write(“carrot.json”)
在这里你还需要跟踪 carrot 类型脚本的哈希:
pry(main)> carrot_type_pute_hash
=> “0x039c2fba64f389575cdecff8173882b97be5f8d3bdb2bb0770d8a7e265b91933”
请注意,你可能会得到和我这里不一样的哈希,这得看你使用的环境。
现在,让我们来试试 ckb-standalone-debugger:
$ git clone https:///nervosnetwork/ckb-standalone-debugger
$ cd ckb-standalone-debugger/bins
$ cargo build –release
$ ./target/release/ckb-debugger -l 0.0.0.0:2000 -g type -h 0x039c2fba64f389575cdecff8173882b97be5f8d3bdb2bb0770d8a7e265b91933 -t carrot.json
注意,你可能需要根据你的环境,调整 carrot 类型脚本的哈希或者 carrot.json 的路径。现在让我们试试在一个不同的终端内通过 GDB 连接调试器:
$ sudo docker run –rm -it -v `pwd`:/code nervos/ckb-riscv-gnu-toolchain:bionic-20191012 bash
root@66e3b39e0dfd:/# cd /code
root@66e3b39e0dfd:/code# riscv64-unknown-elf-gdb carrot
GNU gdb (GDB) 8.3.0.20190516-git
Copyright (C) 2019 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type “show copying” and “show warranty” for details.
This GDB was configured as “–host=x86_64-pc-linux-gnu –target=riscv64-unknown-elf”.
Type “show configuration” for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type “help”.
Type “apropos word” to search mands related to “word”…
Reading symbols from carrot…
(gdb) target remote 192.168.1.230:2000
Remote debugging using 192.168.1.230:2000
0x00000000000100c6 in _start ()
(gdb)
注意,这里的 192.168.1.230 是我的工作站在本地网络中的 IP 地址,你可能需要调整该地址,因为你的计算机可能是不同的 IP 地址。现在我们可以试一下常见的 GDB 调试过程:
(gdb) b main
Breakpoint 1 at 0x106b0: file carrot.c, line 6.
(gdb) c
Continuing.
Breakpoint 1, main (argc=0, argv=0x400000) at carrot.c:6
6 size_t index = 0;
(gdb) n
7 uint64_t len = 0;
(gdb) n
11 len = 6;
(gdb) n
12 memset(buffer, 0, 6);
(gdb) n
13 ret = ckb_load_cell_data(buffer, &len, 0, index, CKB_SOURCE_OUTPUT);
(gdb) n
14 if (ret == CKB_INDEX_OUT_OF_BOUND) {
(gdb) n
18 int cmp = memcmp(buffer, “carrot”, 6);
(gdb) n
19 if (cmp) {
(gdb) p cmp
$1 = -99
(gdb) p buffer[0]
$2 = 0 ’ 00’
(gdb) n
20 return -1;
这里我们可以看到哪里出问题了:buffer 中第一个字节的值是 0,这和 c 不同,因此我们的 buffer 和 carrot 不同。条件 if (cap) { 没有跳转到下一个循环,而是跳到了 true 的情况,返回了 -1,表明与 carrot 匹配。出现这样问题的原因是,当两个 buffers 相等的时候,memcmp 将会返回 0,当它们不相等的时候,将返回非零值。但是我们没有测试 memcmp 的返回值是否为 0,就直接在 if 条件中使用了它,这样 C 会把所有的非零值都视为 true,这里返回的 -99 就会被判断为 true。对于初学者而言,这是在 C 中会遇到的典型的错误,我希望你不会再犯这样的错误。
现在我们知道了错误的原因,接下来去修复 carrot 脚本中的错误就非常简单了。但是正如你看到的,我们设法从 CKB 上获取一笔错误交易在运行时的状态,然后通过 GDB(一个业界常见的工具)来对其进行调试。而且您在 GDB 上现有的工作流程和工具也可以在这里使用,是不是很棒?
然而,GDB 仅仅是现代软件开发中的一部分。动态语言在很大程度上占据了主导地位,很多程序员都使用基于 REPL 的开发/调试工作流。这与编译语言中的 GDB 完全不同,基本上你需要的是一个运行的环境,你可以输入任何你想要与环境进行交互的代码,然后得到不同的结果。正如我们将在这里展示的,CKB 也会支持这种类型的开发/调试工作流。
在这里,我们将使用 ckb-duktape 来展示基于 JavaScript 的 REPL。但是请注意,这只是一个 demo 用来演示一下工作流程,没有任何东西阻止您将自己喜爱的动态语言(不管是 Ruby、Rython、Lisp 等等)移植到 CKB 中去,并为该语言启动 REPL。
首先,让我们尝试编译 duktape:
$ git clone https:///nervosnetwork/ckb-duktape
$ cd ckb-duktape
$ sudo docker run –rm -it -v `pwd`:/code nervos/ckb-riscv-gnu-toolchain:bionic-20191012 bash
root@982d1e906b76:/# cd /code
root@982d1e906b76:/code# make
riscv64-unknown-elf-gcc -Os -DCKB_NO_MMU -D__riscv_soft_float -D__riscv_float_abi_soft -Iduktape -Ic -Wall -Werror c/entry.c -c -o build/entry.o
riscv64-unknown-elf-gcc -Os -DCKB_NO_MMU -D__riscv_soft_float -D__riscv_float_abi_soft -Iduktape -Ic -Wall -Werror duktape/duktape.c -c -o build/duktape.o
riscv64-unknown-elf-gcc build/entry.o build/duktape.o -o build/duktape -lm -Wl,-static -fdata-sections -ffunction-sections -Wl,–gc-sections -Wl,-s
riscv64-unknown-elf-gcc -Os -DCKB_NO_MMU -D__riscv_soft_float -D__riscv_float_abi_soft -Iduktape -Ic -Wall -Werror c/repl.c -c -o build/repl.o
riscv64-unknown-elf-gcc build/repl.o build/duktape.o -o build/repl -lm -Wl,-static -fdata-sections -ffunction-sections -Wl,–gc-sections -Wl,-s
root@982d1e906b76:/code# exit
你需要在这里生成 build/repl 二进制文件。和 carrot 的例子类似,我们先将 duktape REPL 的二进制文件部署在 CKB 上:
pry(main)> api = CKB::API.new
pry(main)> wallet = CKB::Wallet.from_hex(api, “<your private key>”)
pry(main)> wallet2 = CKB::Wallet.from_hex(api, CKB::Key.random_private_key)
pry(main)> duktape_repl_data = File.read(“build/repl”)
pry(main)> duktape_repl_data.bytesize
=> 283048
pry(main)> duktape_repl_tx_hash = wallet.send_capacity(wallet2.address, CKB::Utils.byte_to_shannon(300000), CKB::Utils.bin_to_hex(duktape_repl_data), fee: 310000)
pry(main)> duktape_repl_data_hash = CKB::Blake2b.hexdigest(duktape_repl_data)
pry(main)> duktape_repl_type_script = CKB::Types::Script.new(code_hash: duktape_repl_data_hash, args: “0x”)
pry(main)> duktape_repl_cell_dep = CKB::Types::CellDep.new(out_point: CKB::Types::OutPoint.new(tx_hash: duktape_repl_tx_hash, index: 0))
我们还需要创建一笔包含 duktape 脚本的交易,我这里使用一个非常简单的脚本,当然你可以加入更多的数据,这样你就可以在 CKB 上玩起来了!
pry(main)> tx = wallet.generate_tx(wallet2.address, CKB::Utils.byte_to_shannon(100), use_dep_group: false, fee: 5000)
pry(main)> tx.outputs[0].type = duktape_repl_type_script
pry(main)> tx.cell_deps << duktape_repl_cell_dep
pry(main)> tx.witnesses[0] = “0x”
然后让我们把它转存到文件中,并检查 duktape 类型脚本的哈希:
pry(main)> CKB::MockTransactionDumper.new(api, tx).write(“duktape.json”)
=> 2765824
pry(main)> duktape_repl_type_pute_hash
=> “0xa8b79392c857e29cb283e452f2cd48a8e06c51af64be175e0fe0e2902c482837”
与上面不同的是,我们不需要启动 GDB,而是可以直接启动程序:
$ ./target/release/ckb-debugger -g type -h 0xa8b79392c857e29cb283e452f2cd48a8e06c51af64be175e0fe0e2902c482837 -t duktape.json
duk>
你可以看到一个 duk> 提示你输入 JS 代码!同样,如果遇到错误,请检查是否需要更改类型脚本的哈希,或者使用正确的 duktape.json 路径。我们看到常见的 JS 代码可以在这里工作运行:
duk> print(1 + 2)
3
= undefined
duk> function foo(a) { return a + 1; }
= undefined
duk> foo(123)
= 124
您还可以使用与 CKB 相关的功能:
duk> var hash = CKB.load_script_hash()
= undefined
duk> function buf2hex(buffer) { return Array.prototype.map.call(new Uint8Array(buffer), function(x) { return (’00’ + x.toString(16)).slice(-2); }).join(’’); }
= undefined
duk> buf2hex(hash)
= a8b79392c857e29cb283e452f2cd48a8e06c51af64be175e0fe0e2902c482837
请注意,我们在这里得到的脚本哈希正是我们当前执行的类型脚本的哈希!这将证明 CKB 系统调试在这里是有效的,我们也可以尝试更多有趣的东西:
duk> print(CKB.SOURCE.OUTPUT)
2
= undefined
duk> print(CKB.CELL.CAPACITY)
0
= undefined
duk> capacity_field = CKB.load_cell_by_field(0, 0, CKB.SOURCE.OUTPUT, CKB.CELL.CAPACITY)
= [object ArrayBuffer]
duk> buf2hex(capacity_field)
= 00e40b5402000000
这个 00e40b5402000000 可能在一开始看起来有点神秘,但是请注意 RISC-V 使用的是 little endian(低字节序),所以如果在这里我们将字节序列颠倒,我们将得到 00000002540be400,在十进制中正好是 10000000000。还要记住,在 CKB 中容量使用的单位是 shannons,所以 10000000000 正好是 100 个字节,这正是我们生成上面的交易时,想要发送的代币的数量!现在你看到了如何在 duktape 环境中与 CKB 愉快地玩耍了 。
我们已经介绍了两种不同的在 CKB 中调试的过程,你可以随意使用其中一种(或者两种)。我已经迫不及待地想看你们在 CKB 上玩出花来啦!
Nervos Community 致力于成为最好的 Nervos 社区,我们将持续地推广和普 及 Nervos 技术,深入挖掘 Nervos 的内在价值,开拓 Nervos 的无限可能, 为每一位想要深入了解 Nervos Network 的人提供一个优质的平台。
以上就是关于gg修改器的root是哪个_gg修改器root是什么意思的全部内容,感谢大家的浏览观看,如果你喜欢本站的文章可以CTRL+D收藏哦。
gg修改器怎样免root版,GG修改器 – 极简免root版 大小:14.47MB3,630人安装 GG修改器作为常用的辅助工具,可以帮助玩家在游戏中获取更多的资源以及提供更好的游……
下载gg修改器怎么无root,GG修改器怎么不用root 大小:8.61MB5,076人安装 1、兼容性广泛,支持各种安卓手机以及安卓模拟器 2、支持虚拟空间,实现无root工作……
下载平行空间gg修改器最新版,平行空间gg修改器最新版:超越传统游戏辅助工具的全新突破 大小:15.40MB3,826人安装 在现代社会中,游戏已经成为人们生活中不可或缺的一部分。而游戏辅助工具的出现更是……
下载gg修改器无root运行,优秀的GG修改器无root运行给游戏带来了畅玩体验 大小:13.08MB3,778人安装 在游戏领域,作为一款热门游戏,可以说《王者荣耀》的人气十分高涨,掀起了一波MOBA……
下载gg修改器免root版正版_gg修改器免root版大全 大小:13.56MB4,945人安装 大家好,今天小编为大家分享关于gg修改器免root版正版_gg修改器免root版大全的内容……
下载gg游戏修改器钢铁之躯2,探秘GG游戏修改器–钢铁之躯2完美助手 大小:7.78MB3,688人安装 对于众多游戏玩家来说,玩游戏不只是一种娱乐方式,更是一种热爱和精神追求。而在这……
下载gg修改器怎么下免root优化_gg修改器免root修改 大小:6.18MB4,933人安装 大家好,今天小编为大家分享关于gg修改器怎么下免root优化_gg修改器免root修改的内……
下载gg修改器弄成中文,GG修改器 – 将游戏变得更好更有趣 大小:12.97MB3,854人安装 随着游戏的普及,越来越多的玩家开始追求更好的游戏体验。而GG修改器作为一款常用的……
下载gg修改器要用root吗_gg修改器一定要root吗 大小:10.72MB5,071人安装 大家好,今天小编为大家分享关于gg修改器要用root吗_gg修改器一定要root吗的内容,……
下载gg修改器下载中文无病毒_gg修改器官网下载无病毒无广告 大小:7.17MB4,920人安装 大家好,今天小编为大家分享关于gg修改器下载中文无病毒_gg修改器官网下载无病毒无……
下载