Skip to content

编写您的第一个合约

TON(Telegram Open Network)合约是一个具有状态和代码的孤立对象,可以发送和接收消息,并提供用于离线读取合约状态的获取方法。

合约的代码决定了:

  • 它如何操作自身的状态,
  • 它如何响应传入的消息,
  • 它如何向离线世界公开自身的状态。

合约示例

这个合约允许任何网络中的人增加计数器,存储合约的所有者,并向离线世界公开计数器值和所有者地址。

solidity
contract Counter {
 
    owner: Address;
    counter: Int as uint32;
 
    init(owner: Address) {
        self.owner = owner;
        self.counter = 0;
    }
 
    receive("increment") {
        self.counter = (self.counter + 1);
    }
 
    get fun counter(): Int {
        return self.counter;
    }
 
    get fun owner(): Address {
        return self.owner;
    }
}

合约状态(state)和初始化(init)

这个合约有两个状态变量,它们在合约调用之间保持不变:ownercounter。这些状态变量在合约头部声明,并在 init 函数中初始化。

init 函数在部署合约之前被调用

counter 变量被声明为 Int 类型的 uint32,这意味着它将以 uint32 的形式存储在合约状态中。

  1. Int 类型用于表示合约代码中的整数数字
  2. Int 是 257 位有符号整数。
  3. 大小检查仅在存储时执行。
  4. 溢出 Int 会导致异常并中止交易。

接收器 Receiver

receive("increment") 的表示意味着声明一个接收器函数,当发送一个值为 "increment" 的文本到合约时,该函数将被调用。该函数体可以修改合约的状态并向其他合约发送消息。不可能直接调用接收器。如果需要重用一些逻辑,可以声明一个函数并从接收器中调用它。

这里列出了几个接收器函数。所有接收器函数按照以下列出的顺序进行处理:

  • receive() - 当向合约发送空消息时调用
  • receive("message") - 当发送带有特定注释的文本消息到合约时调用
  • receive(str: String) - 当向合约发送任意文本消息时调用
  • receive(msg: MyMessage) - 当发送类型为 MyMessage 的二进制消息到合约时调用
  • receive(msg: Slice) - 当发送未知类型的二进制消息到合约时调用
  • bounced(msg: Slice) - 当传出消息被退回时调用

面相消息的编程:每一个合约就是一个对象,这些合约对象之间通过传递消息来进行通信,而不是直接互相调用。这种设计可以消除调用者和接收者之间的耦合,同时对象可以随时订阅和取消订阅消息,这让对象之间的依赖关系和更新变得更加容易。

Tact使用receive()实现不同合约直接的通信,这样合约之间既进行了隔离,降低了风险,又简化了交互流程,大大提升了合约开发的安全性。

获取器 Getters

这个合约中有两个获取器,分别是 counter 和 owner,用于返回当前计数器值和合约所有者。这些获取器不能被其他合约访问,只能被导出到链下世界。