Dear:
微信群"Nervos CKB Wallet & Toolchain"的聊天记录如下:
我是出来打酱油的 3:32 PM
首先 alice 转币给 bob,那么 bob 一定要给 alice 提供一个 “地址” 或者其他表示符。这个表示符,其实就是 lock。这样 alice 转币给 bob 的过程,其实就是 bob 提供给 alice 一个 lock,alice 创建一个 celloutput,这个 celloutput 的 lock 就是 bob 提供的值。
我是出来打酱油的 3:32 PM
紧接着说 lock 的选择过程
Cipher·王博 3:41 PM
等待中……
我是出来打酱油的 3:42 PM
不过要解释 lock 的选择过程,为了说明方便,我们先跳过 lock 的选择,我们先假设 bob 已经通过某种方式选择了一个 lock,alice 也给 bob 转了一定的币(换句话说,alice 创建了一个 celloutput A,这个 celloutput 的 lock 是 bob 提供的),现在 bob 如果想花获得的这些币,那么 bob 要怎么做?
很显然,bob 需要创建一个 tx,这个 tx 中有一个 cellinput,这个 input 指向上面创建的 celloutput A。同时这个 input 里面也要提供一个 unlock 脚本,用来告诉 CKB bob 是可以解锁这个 celloutput A 的。
那么很显然,这里其实是有个问题:如果 unlock 脚本不加任何限制,那么 alice 给 bob 发币之后,这里其实 charlie 就可以用 always_success_script 解锁这个 celloutput A 了,bob 就丢币了。
所以为了限制这个问题,我们增加了 P2SH 的验证方式:我们要求每一个 input 中的 unlock 脚本,在通过一种预先订好的算法 hash 之后,得到的 hash 结果,必须能匹配 input 所引用的 output 中的 lock。这样回到上面的例子,charlie 如果直接填写 always_success_script,那么 P2SH 验证时会报错,也就保证了 bob 不会丢币。但是 bob 在花币时,可以在 unlock 脚本中写上他预先订好的脚本,配上他自己的签名,就可以花币了。
那么回到最开始的问题,bob 怎么确定自己的 lock?目前我觉得应该是这样的方式:
1. bob 选择一个签名的合约,比如 secp256k1,每一个用于签名的合约会有一个自己的合约模版可以使用
2. bob 在模版中确定好的位置填入自己的 public key,生成针对自己的 public key 的签名合约
3. bob 再用跟上面说的 hash unlock 脚本一样的方式,hash 自己的签名合约,得到的结果,就可以作为 lock 使用了
Cipher·王博 3:45 PM
懂了[强]
Cipher·王博 3:45 PM
“生成针对自己的 public key 的签名合约”,应该不是字面意思吧。
Cipher·王博 3:46 PM
否则每个人都要重复放一段代码
ashchan 3:46 PM
这里 signed args 的作用
我是出来打酱油的 3:46 PM
其实这个比想象的简单。可以认为合约的模版就是一个 JSON object,“生成针对自己的 public key 的签名合约”,就是把自己的 public key 给 push 到这个 JSON object 中的一个 array,形成一个新的 JSON object
我是出来打酱油的 3:47 PM
由于有合约共享机制的存在,这个 JSON object 其实不会很大,几百个字节差不多了。变成 CKB 链上的 二进制结构会更小
Cipher·王博 3:47 PM
ok,那么问题来了,节点如果只能看到 lockhash 的话,它怎么找到对应的签名合约做验证呢。
ashchan 3:47 PM
对于同一个用户来说,针对一个算法,是生成一次 JSON Object 就可以多次使用了?
陈迪波 3:48 PM
用户会强制生成此Public key的签名合约么?同时该合约客户端如何判断是该用户的?
我是出来打酱油的 3:48 PM
我一个一个回答,稍安勿躁
我是出来打酱油的 3:50 PM
「 Cipher·王博: ok,那么问题来了,节点如果只能看到 lockhash 的话,它怎么找到对应的签名合约做验证呢。 」
- - - - - - - - - - - - - - -
这里其实跟 bitcoin 的 P2SH 一样,lock hash 是可以帮助隐藏 public key 的。所以一个 general 的答案是如果只看到 lock hash,是没办法找到对应的签名合约。这里可以通过几个方式来缓解这个问题:
1. 首先如果考虑只有创建 lock hash 的人使用 cell 的话,他是知道自己用的什么签名合约的
2. 如果在钱包端有更广泛的需求,那么我们可以在 lock hash 的上面再添加一层,包装成一个 address,这个 address 里面可以 encode lock hash,与具体用的什么签名合约
我是出来打酱油的 3:51 PM
「 陈建明: 对于同一个用户来说,针对一个算法,是生成一次 JSON Object 就可以多次使用了? 」
- - - - - - - - - - - - - - -
严格地说是对于一个 priv/pub keypair,针对一种算法,可以生成一次 JSON Object 多次使用
我是出来打酱油的 3:52 PM
「 陈迪波: 用户会强制生成此Public key的签名合约么?同时该合约客户端如何判断是该用户的? 」
- - - - - - - - - - - - - - -
其实可以把这个强制生成此 public key 签名合约的过程,看作是先生称一个 priv key,然后生成钱包地址的过程,剩下的可以按照普通钱包地址同样处理,这样是不是就容易理解了。
Cipher·王博 3:53 PM
ok,我懂了。
Cipher·王博 3:53 PM
感谢
Cipher·王博 3:54 PM
还有个问题,如果引用的算法 cell 被销毁了怎么办
我是出来打酱油的 4:00 PM
「 Cipher·王博: 还有个问题,如果引用的算法 cell 被销毁了怎么办 」
- - - - - - - - - - - - - - -
首先我必须说这个的确是目前没有特别完美的解决方式的问题,目前的解决方案是有可能变的。现在我听到的最实际的办法就是添加一个新的概念叫做 embeds,这个可以用来直接在一个 tx 里添加一个原始合约,这样如果一个引用的算法 cell 被销毁,用户可以利用 embeds 自己添加上这个合约,继续使用。但是这个办法有个坑就是添加原始合约会大大增加 tx 的大小,可能开销会大上很多,所以这个并不一定是个广泛适用的办法。
当然一个签名算法的 cell 也可以为了吸引用户,自己给自己用一个 always_faliure 的 lock,保证这个 cell 没办法被销毁。但是这样的坏处就是会有 CKB capacity 永远的流失了,也不一定是个好办法。
Cipher·王博 4:02 PM
cell hash = cell data hash = cell unique id 对吗?
我是出来打酱油的 4:03 PM
我不太清楚我们哪里有 cell hash。实际在合约里用到的是两个结构,一个是 cell data hash,一个是 cell 的 out_point
Cipher·王博 4:04 PM
cell 的唯一标识是什么
Cipher·王博 4:04 PM
是如何定义的
我是出来打酱油的 4:05 PM
我觉得 cell 的唯一标识应该是 out_point,包含 cell 所在的 transaction hash 和这个 cell 在 transaction 中的 index。
@iåÑ turning off notifications @soledad 能不能帮我确认下这个
猫空 4:05 PM
应该是out_point{ tx_id, index)
猫空 4:06 PM
tx_id => tx_hash
Cipher·王博 4:08 PM
got