Ton 区块链 Minter与Wallet的合约部署关联细节

作者:林冠宏 / 指尖下的幽灵。转载者,请: 务必标明出处。

GitHub : https://github.com/af913337456/

出版的书籍:


Ton 区块链 Minter与Wallet的合约部署关联细节

Ton 区块链的其他系列文章:Ton 区块链的官方 类ERC20-Token 智能合约代码-Transfer部分解析

在上一篇文章中,我介绍到 Ton 区块链的合约是分片的,尤其体现在 Token 经济合约中。那么既然有关联关系的话,在部署的时候是怎样的把这种关系绑定的呢?这是这篇文章要讲解的点。

假设现在 A Token 的合约是由 Minter 合约和 Wallet 合约组成的,根据官方的 Token 合约例子,可以知道在 Minter 合约中的 LoadData 函数的最后一个返回是 Wallet 合约的 Code 代码,如下:

(int, slice, cell, cell) load_data() inline {
  slice ds = get_data().begin_parse();
  return (
      ds~load_coins(), ;; total_supply
      ds~load_msg_addr(), ;; admin_address 就是 jetton_master_address
      ds~load_ref(), ;; content
      ds~load_ref()  ;; jetton_wallet_code 就是这个
  );
}

提示: 上面代码中的 admin_address 就是 Wallet 合约中的 jetton_master_address

意味着,在部署 Minter 合约的时候,使用客户端的部署代码中,要把 WalletCode 作为参数传递到部署方法中,这一点在官方的 Js 部署代码中可以得到考证,如下:

const content = jettonContentToCell({type:1,uri:contentUrl});

    // wallet 合约的代码。在合约编译后就能获取了,不需要上链
    const wallet_code = await compile('JettonWallet'); 

    const minter  = JettonMinter.createFromConfig({admin,
                                                  content,
                                                  wallet_code, // wallet code
                                                  }, 
                                                  await compile('JettonMinter')); // Minter 合约的代码
    // 这里的部署就等于把这个 Minter 的和 wallet 的绑定上了
    await provider.deploy(minter, toNano('0.05')); // deploy 部署

部署操作的链上存储函数是下面这个,对应 LoadData 的 SaveData,也是 Minter 合约中的。

() save_data(int total_supply, slice admin_address, cell content, cell jetton_wallet_code) impure inline {
  set_data(begin_cell()
            .store_coins(total_supply)
            .store_slice(admin_address)
            .store_ref(content)
            .store_ref(jetton_wallet_code) // Wallet 合约 code
           .end_cell()
          );
}

综上,我们不难得出结论:即 Minter 和 Wallet 的绑定,是在部署 Minter 合约的时候,把 Wallet 的合约编译后的 Code 作为参数传递到部署函数中,最后被存储到链上的 Minter 合约中,完成绑定的。

上面的 Wallet 的 Code 在 Minter 合约中的核心作用是参与计算出用户的 Wallet 合约地址。也就是前个文章中所提到的和用户一一对应 Wallet 合约。在 Minter 下面的代码片段中可以看出:

slice get_wallet_address(slice owner_address) method_id {
    (int total_supply, slice admin_address, cell content, cell jetton_wallet_code) = load_data();
    return calculate_user_jetton_wallet_address(owner_address, my_address(), jetton_wallet_code);
}

get_wallet_address 函数对应到客户端的 API 调用,它将使用 owner_address 即参数过来的客户端钱包地址计算出这个客户的 wallet_address 然后返回给客户端。客户端在拿到这个地址后,便可进行 Wallet 合约的调用,实现 Transfer 转账操作了,这里也和上个文章的源码部分对应上了。

那么 Wallet 合约是否需要部署?

答案是不需要的,根据官方文章的描述,是不需要的,用户在使用这个 Token 的时候,会被自动创建一份对应的 Wallet 合约。但也可以部署,之所以不需要是因为在部署 Minter 合约的时候已经把 Wallet 的 Code 数据传递上链了。

至此。Minter合约 和 Wallet合约部署关联细节结束。

posted @ 2024-06-12 13:37  指尖下的幽灵  阅读(32)  评论(0编辑  收藏  举报