APP
TON的幕后花絮:部署智能合约的经验教训,第2部分
2020-02-15 39018 0


技术分析

这是我们在Telegram开放网络上集成支付渠道的系列文章中的第二篇。在第一部分中,我们介绍了网络,详细介绍了比赛经验,并解释了同步和异步智能合约的工作方式。作为该系列的下一个补充,本文详细介绍了我们在9月份TON比赛期间如何在网络上构建同步支付渠道。在这里,我们仅讨论Fift(TON的通用编程语言)和FunC(TON的用于编写智能合约的编程语言)。

TON白皮书提供了有关支付渠道的更深入的信息,但我们将再次简要说明它们。

相关:TON的幕后花絮:部署智能合约的经验教训,第1部分

同步支付通道允许使用链上资产在两个用户之间链下发送交易。在我们的情况下-GRAM。一方不可能欺骗另一条链外交易,并且交易比执行第一层区块链交易要快得多,因为仅使用用户设备即可完成交易而不必写入区块链。有两个基本操作:入金和出金。撤资是实施过程中最具挑战性的一项。

为了正确退出,用户需要提供有关其频道状态的最新信息。状态由每个参与者的步骤和数字签名组成,这意味着不可能用未经双方认可的数据来提供正确的状态。

要部署智能合约,您需要在Fift中编写一个部署脚本并将其编译为.boc(单元包)文件。这样做会使多个单元相互链接。然后需要将GRAM发送到在部署脚本执行过程中收到的地址。一旦在地址上有GRAM,将.boc文件发送到网络,合同将被部署。

要进行函数调用,请编写一个脚本,该脚本将向已部署的智能合约发送外部消息。

基本上,TON上的任何内容都是具有某些引用的单元格。一袋信元是由Telegram团队设计的数据结构。这是一个演员模型。TON白皮书提供了更多详细信息:“一切都是一袋牢房。” 您正在构建一个单元,该单元在部署时将与另一个单元交互。

每个点对点支付渠道都是一个智能合约。让我们看一下智能合约的各个部分。

相关:电报开放网络的期望:开发人员的观点

部署部分

序列化的Fift脚本用于部署合同。它被保存为.boc文件,并通过网络的轻客户端TON Cli发送到网络。

堆栈上的最新单元是执行上述Fift脚本的结果。

Fift部署脚本的通常部分包括(但不限于):

  1. 智能合约的代码作为一个单元格(通常用FunC编写,然后编译为Fift ASM代码,并使用path-to-compiled-asm.fif包含在主.fif文件中)。
  2. 智能合约的初始存储(请参见下文)。
  3. 新的智能合约地址(来自智能合约初始状态的哈希,还包括智能合约代码单元格和初始存储单元格)。
  4. recv_external函数的第一次调用的参数(参数的数量和类型取决于协定)。
  5. 一个用于初始化的外部消息单元,它将被序列化为字节并打包到.boc文件中,该文件包含第1至4点中的所有数据以及一些尚缺乏文档的其他数据。

当.boc编译,克需要的具体数额被发送到智能合同地址。必须将.boc文件发送到网络以初始化智能合约。GRAM的数量取决于所部署的智能合约的外部消息单元(不仅是其代码)的计算大小和数量。天然气×天然气价格是从已部署的智能合约余额中获取的。这是部署期间支付天然气所需的最低费用。

存储的表示形式:

  1. seqno 32位
  2. contract_status 4位
  3. first_user_pubkey。第一方的公开密钥256位
  4. second_user_pubkey。第二方的公钥256位
  5. time_to_send。提交第一个实际状态后的发送时间32位(有效期至2038年)
  6. depositSum。两个参与者的存款总和,最多121位
  7. state_num 64位。当前发生的状态数量

一个信元最多包含1023位,并包含对其他信元的四个引用。我们能够将整个存储空间放在一个单元中,而无需一个参考。我们的存储最多可占用765位。

所有智能合约状态

0x0-部署状态

0x1 —通道已打开并准备存入

0x2-用户存款1

0x3-用户存款2

0x4 —存款被冻结。可以为智能合约提供状态

0x5-用户1提供了状态

0x6 —用户2已提供状态

0x7 —通道已关闭

存入

存款功能从简单的钱包(转账)接收消息,并带有额外的有效载荷。

将GRAM存入通道:

  1. 用户生成一个附加的正文有效载荷,该正文有效载荷包括消息(例如1位)及其在单独的.fif文件中的签名。
  2. 主体有效负载被编译为.boc文件。
  3. 主体有效负载从此.boc文件加载到.fif文件中,作为主体单元“传输”参考(.fif负责从钱包中传输GRAM)。
  4. 该recv_external函数被调用以参数(存款金额与该信道的目的地地址)时编译.fif文件被发送到网络。
  5. 该send_raw_message执行功能。存放的GRAM和其他主体有效负载将发送到P2P通道智能合约目标地址。
  6. P2P通道智能合约的recv_internal函数被调用。GRAM由通道合同接收。

如果P2P通道智能合约的状态为0x1或0x2或0x3,则可以调用存款功能。

检查状态的FunC代码:

1个

只有公开密钥(写在初始存储中)的所有者才可以进行存款。智能合约检查将通过recv_internal函数接收的每个内部消息的签名。如果消息是由公共密钥所有者之一签名的,则合同状态将更改为0x2或0x3(如果是公共密钥1,则为0x2,如果是公共密钥2,则为0x3)。如果所有用户都进行了存款,则在同一函数调用中合同状态将变为0x4。

负责更改合同状态的FunC代码:

2

退款

如果交易对手未按时存入资金,则可以退还资金。

为此,用户需要通过外部消息提供其地址和签名。如果提供的签名属于公钥1或公钥2(进行存款的人)并且合同状态为0x2或0x3,则资金将退还。

负责验证退款申请的FunC代码:

3

退出

每个人都应提供退出状态,该状态的签名以及正文消息的签名。

州详情:

  1. 智能合约地址(排除从前具有相同参与者的P2P通道进入正确状态的可能性)。
  2. 第一位参与者的最终余额。
  3. 第二个参与者的最终余额。
  4. 州号。

正文消息签名存储在主切片中,状态存储在单独的引用中,状态签名作为对“签名”引用的引用存储,以避免单元溢出。

提款步骤:

  1. 检查正文消息签名并确定参与者。

4

  1. 检查是否轮到参与者了,或者自从上次进入状态以来已经过了24小时。将当前参与者的回合(0x5或0x6)写入合同状态。

为first_user_pubkey的所有者正确的正文消息签名的示例:

5

然后,我们需要验证写入状态的智能合约地址是否为实际的合约地址:

6

接下来,我们需要验证状态下的签名:

7

之后,有两个断言:

  1. 从存储中存入的金额应等于参与者总余额的总和。
  2. 新输入的状态号必须大于或等于前一个。

8

在new_state_num> state_num的情况下,我们需要存储new_state_num,其新的time_to_send等于now()+ 86401(距当前时间24小时),并写入实际合同状态(如果第一个参与者拨打电话,则为0x5,否则为0x6) 。

在另一种情况下,如果new_state_num == state_num,则需要对“签名”引用添加另外两个引用,其中每个参与者的地址均在其地址下方。

如果签名正确,则从一个地址中取出GRAM,并将其放入所有者的地址中。

9

每次成功调用一次,我们都需要存储所有存储数据,即使它没有改变。

未解决的问题

假定第一位用户部署了合同,而参与者则同意了佣金。在我们的案例中,关于佣金的协议正在链下达成。

考虑到玩家可以写下无关的状态并在此之后记录实际状态,我们还没有弄清楚如何计算总佣金。请记住,每次成功调用recv_internal或recv_external函数时,我们都需要从P2P通道智能合约中支付费用。

如前所述,我们需要在不可反弹的未来智能合约地址中添加一些GRAM,以便对其进行初始化。

在比赛的最后一天,TON的开发商做出一个承诺的stdlib.fc库,允许获得实际的智能剩余合同,新的功能。

10

欢迎提出解决此问题的建议!

结论

FunC和Fift允许任何开发人员访问软件工程的低端世界,为已经习惯以太坊或任何其他智能合约平台的区块链开发人员提供新的机会和功能。TON是分片的区块链非常重要,因此在其上实施智能合约更具挑战性。例如,以太坊的合约是同步运行的,不需要处理诸如等待其他合约的答案之类的情况。

智能合约通信的异步方式是使其具有可伸缩性的唯一选择,TON具有这些选择。我们的解决方案最终要比Solidity难以实施,但是总会有一个权衡。绝对有可能在TON上建立高级智能合约,并且TON团队处理该合约的方式令人印象深刻。我们期待看到更多有助于部署和建立FunC合同的库和工具。

我们非常喜欢所有任务,并希望我们有更多的时间来执行所有任务。尽管如此,我们还是在TON竞赛中获得了两个奖项:最佳同步支付渠道第一名和最佳异步支付渠道第三名。

我们将在第三部分中分享我们自己的个人反馈。

这里表达的观点,思想和观点仅是作者的个人观点,不一定反映或代表Cointelegraph的观点和观点。

本文由Nick Kozlov和Kirill Kuznetsov共同撰写。

尼克·科兹洛夫(Nick Kozlov)是Button Wallet的CTO和联合创始人,Button Wallet是软件开发人员和研究员,也是TON竞赛的获胜者之一。

Kirill Kuznetsov是Button Wallet的共同创始人,也是TON比赛的获胜者之一。

内容来源:币源社区

版权声明:本文仅为传播消息之用,不代表币源社区立场,文章不构成投资建议。如需转载,请务必注明文章原作者以及来源,部分图片来源于网络,我们尊重版权,如有疑问敬请联系,我们将核实并删除。

我要评论
字数上限500
评论(0)