一些问题咨询

大家好!小弟编程方面都是自学属于全职个人独立开发者,做了很多年的APP和web开发,刚接触区块链,了解了下CKB,挺不错,想做DAPP,合约用js,刚看了B站上面Phil的4个视频,有几个问题不是很了解,请教各位大佬:
1.去中心化不像中心化有数据库可以保存数据。ckb去中心化的数据保存读取该如何使用呢?作用域和数据的保存时间是如何的呢?有相关文档或者教程吗?
2.dapp如何调用浏览器插件钱包或者调用其他手机端app钱包 之类的,有示例吗?
3.合约部署好后dapp该如何调用执行合约呢?

4 Likes
  1. CKB 上的数据按照 cell 的数据形式进行保存的,理解 cell 模型可以参考:理解CKB的Cell模型 。对于未被使用的 live cell(CKB 的 cell 模型和比特币一样,都是 UTXO 模型,未被使用的 live cell 等同于未被使用的 BTC 的 UTXO)会被节点保存,后续新生成的 cell,可以去使用/引用这些 live cells。开发文档可以参考官方文档社区文档
  2. dapp 调用浏览器插件钱包的话,目前还没有基于 CKB 的调用标准,但是 PW-SDK 另辟蹊径,直接使用了以太坊、EOS、Tron 的钱包调用接口,我们可以直接使用以太坊的基础设施,实现 CKB 转账,参考文档
  3. 简单而言,在 CKB 上部署合约是将合约编译成二进制,放到 cell 的 data 里面的,其他 cell 可以在 lock / type script 引用这个合约的 code_hash 来实现合约的调用。具体的可以参考学姐的系列教程

1.如何使用相关数据呢?如:在链上的以前的数据如何读取?
3.我想知道在dapp上面如何发起这个执行合约的交易呢?应该向什么节点提交吗?具体示例有吗??

所有 live cell 可以直接在链上获取,live cell 内的数据是可以使用的(使用包括:转账、销毁、读取等操作),已经被消费的 dead cell 内的数据是没有办法被再次使用的。

以 SUDT 代币合约为例,SUDT 合约存放在一个 cell 内,在发行一个 SUDT 代币时,需要在 cell_deps 引用这个 SUDT 合约,然后在 output 的 cell 的 type script 内放入 SUDT 合约对应的 code_hash,然后就会执行 SUDT 相关代码。

CKB 是链下计算,链上验证的模型,所有的合约执行不是向链上的一个智能合约输入一个参数,所有的合约执行都是通过拼交易的形式完成的,交易中 input cells 和 output cells 会包含一系列的 lock 和 type 脚本,交易传输到节点这边,节点会验证这些 lock 和 type 脚本,验证通过则交易可以上链,验证不通过直接打回,无法上链。

建议可以先看一下 CKB 编程模型介绍 CKB 结构介绍

还可以参考 理解CKB的Cell模型RFC: Simple UDT Draft SpecRFC: anyone-can-pay lock 以及上面提到的官方教程等。

欢迎加微信:cryptostitch 交流

2 Likes

请问有代码相关的教程吗?如:在合约中如何存储和读取数据的代码?

我这边给你举一个例子吧。

这边我们看一笔,CKB 上 SUDT 的转账:https://explorer.nervos.org/transaction/0x70327161230b36afbf9a44819d2b9e328fe119c053026fabf033fccc6d15ef04 ,交易内容就是h62xyzk5转了一个 COFFEE。

发送者 h62x 的 cell 是这样的

lock script: // 这是 h62x 的锁脚本,codeHash 代表使用的锁合约是 pw-lock,args 代表了 h62x 公钥
{
    "args": "0xc6238a16c799b8cb0df3f19adc71ff40a110c28e",
    "codeHash": "0xbf43c3602455798c1a61a596e0d95278864c552fafe231c063b3fabf97a8febc",  // pw-lock
    "hashType": "type"
}

type script: // 这是 COFFEE 的类型脚本,codeHash 代表该类型脚本使用的合约是 sUDT 合约,args 代表了这个是 COFFEE token
{
    "args": "0x6e97feb7c3b16d9e87faeed7f3dc2d612fd9f541770efe999f931928d2ef846a",
    "codeHash": "0x5e7a36a77e68eecc013dfa2fe6a23f3b6c344b04005808694ae6dd45eea4cfd5",
    "hashType": "type"
}

data: // data 填写的是 COFFEE 的数量
{
    "data": "0x01000000000000000000000000000000"
}

接受者 yzk5 的 cell 是这样的

lock script:  // 这是 yzk5 的锁脚本,codeHash 代表使用的锁合约是 pw-lock,args 代表了 yzk5 公钥
{
    "args": "0xac6ec0e10e4924c9f4067aff77b98f7eed2f7266",
    "codeHash": "0xbf43c3602455798c1a61a596e0d95278864c552fafe231c063b3fabf97a8febc",
    "hashType": "type"
}

type script: // 这是 COFFEE 的类型脚本,codeHash 代表该类型脚本使用的合约是 sUDT 合约,args 代表了这个是 COFFEE token
{
    "args": "0x6e97feb7c3b16d9e87faeed7f3dc2d612fd9f541770efe999f931928d2ef846a",
    "codeHash": "0x5e7a36a77e68eecc013dfa2fe6a23f3b6c344b04005808694ae6dd45eea4cfd5",
    "hashType": "type"
}

data: // data 填写的是 COFFEE 的数量
{
    "data": "0x01000000000000000000000000000000"
}

在这笔交易中,会验证以下内容:

  • h62x 的 lock script
  • h62x 发送的 COFFEE token 的 type script
  • yzk5 接受的 COFFEE token 的 type script

要验证这些东西,就需要读取对应的合约,也就是 pw-lock 合约和 sUDT 合约,然后我们看一下这笔交易的 CellDeps(可以理解为引用合约)

CellDeps
OutPoint.TxHash: 0x71a7ba8fc96349fea0ed3a5c47992e3b4084b031a42264a018e0072e8172e46c // secp256k1_blake160
OutPoint.Index: 0
DepType: dep_group
OutPoint.TxHash: 0x1d60cb8f4666e039f418ea94730b1a8c5aa0bf2f7781474406387462924d15d4 // pwlock-k1-acpl
OutPoint.Index: 0
DepType: code
OutPoint.TxHash: 0xc7813f6a415144643970c2e88e0bb6ca6a8edc5dd7c1022746f628284a9936d5 // sudt
OutPoint.Index: 0
DepType: code

这里面就包含了 secp256k1_blake160pwlock-k1-acplsudt 三个合约(引用secp256k1_blake160 是因为 pwlock-k1-acpl 用到了这个合约)。

这样就实现了读取数据代码,而你再点开那几个合约对应的交易,就是存储合约的交易,就可以看到数据是如何被存储的了。

1 Like

谢谢,我先学习下。看来区块链开发和传统的完全不一样。我以为有个SDK包,直接调用方法,传值什么的就可以用。

typo

1 Like

如果UDT的创建人不小心将cell使用了(UDT合约所在的cell),那么就相当于将UDT销毁了吧?

并不会,可以阅读一下本文:

如果我将cell的output的lock script设置为一个非常特殊的地址上或者设置为一个不存在的hash,是不是就可以保证没人可以使用cell了。
虽然销毁了可以重新创建,可是还是会影响使用感受。像UDT这种还是希望永久存在的。

是的,你在发行token或者创建合约的时候,可以将output的lock script设置成一个任何人都解不开的cell。这样任何人都无法销毁这个token发行合约或者其他任何合约了。当前链上在创世块中部署的脚本都是采用这样的方式进行部署的。