主页 > 老版本imtoken > 波场中文文档

波场中文文档

老版本imtoken 2023-03-25 05:49:54

智能合约波场智能合约介绍

智能合约是一种自动执行其条款的计算机化交易协议。与普通合约一样,智能合约定义了与参与者相关的条款和奖惩机制。合约一旦被激活以太坊哈希值进度查询,就可以按照设定的条款执行,并自动检查承诺条款的执行情况。 Tron 与以太坊上用 Solidity 编写的智能合约兼容。目前推荐的 Solidity 语言版本为 0.4.24 ~ 0.4.25。合约编写编译完成后,部署到波场公链。当部署的合约被触发时,会在公链的各个节点上自动执行。

波场智能合约功能

Tron虚拟机是基于以太坊solidity语言实现的,兼容以太坊虚拟机的特性,但基于tron自身的属性也存在一些差异。

1.智能合约

波场虚拟机运行的智能合约兼容以太坊智能合约功能,合约内容以protobuf形式定义:

message SmartContract {
  message ABI {
    message Entry {
      enum EntryType {
        UnknownEntryType = 0;
        Constructor = 1;
        Function = 2;
        Event = 3;
        Fallback = 4;
        Receive = 5;
        Error = 6;
      }
      message Param {
        bool indexed = 1;
        string name = 2;
        string type = 3;
      }
      enum StateMutabilityType {
        UnknownMutabilityType = 0;
        Pure = 1;
        View = 2;
        Nonpayable = 3;
        Payable = 4;
      }
      bool anonymous = 1;
      bool constant = 2;
      string name = 3;
      repeated Param inputs = 4;
      repeated Param outputs = 5;
      EntryType type = 6;
      bool payable = 7;
      StateMutabilityType stateMutability = 8;
    }
    repeated Entry entrys = 1;
  }
  bytes origin_address = 1;
  bytes contract_address = 2;
  ABI abi = 3;
  bytes bytecode = 4;
  int64 call_value = 5;
  int64 consume_user_resource_percent = 6;
  string name = 7;
  int64 origin_energy_limit = 8;
  bytes code_hash = 9;
  bytes trx_hash = 10;
}

origin_address:合约创建者地址 contract_address:合约地址 abi:合约所有函数的接口信息 bytecode:合约字节码 call_value:合约调用传入的trx数量 consume_user_resource_percent:开发者名称设置的调用者资源扣除百分比:合约名称 origin_energy_limit:开发者在合约调用过程中可以消耗的能量上限,必须大于0。对于旧合约,部署时未提供设置该值的参数,将存储为0 ,但是会按照1000万能量的上限来计算。开发者可以通过updateEnergyLimit接口重新设置值以太坊哈希值进度查询,新值也必须大于0。

通过另外两种 grpc 消息类型 CreateSmartContract 和 TriggerSmartContract 创建和使用智能合约

2.合约函数的使用

函数调用可以分为常量函数和非常量函数两种。常量函数是指用view/pure/constant修饰的函数。结果将直接在调用节点上返回,不会以交易的形式广播。非常量函数是指需要以事务的形式广播的方法调用。该函数会改变链上数据的内容,比如转账、改变合约内部变量的值等。

注意:如果合约内部使用了 CREATE 指令,即使使用 view/pure/constant 来装饰动态创建的合约方法,合约方法仍然会被视为非常量函数,形式为 a要处理的交易。

消息调用可以向其他合约发起函数调用,或者将trx转入合约账户或非合约账户。与普通波场TRON触发合约类似,消息调用也具有调用的发起者、接收者、数据、转账金额、扣减、返回值等属性。每个消息调用都可以递归地生成新的消息调用。合约可以决定应该在其内部消息调用中发送和保留多少剩余能量。如果调用内部消息时发生 OutOfEnergyException(或任何其他异常),它将返回 false,但不会作为异常抛出。此时,只会消耗内部消息调用发送的gas。如果没有指明消息调用中传递的cost call.value(energy),则扣除所有剩余的能量。

有一种特殊类型的消息调用称为委托调用。它与一般消息调用的区别在于,目标地址的代码会在发起调用的合约上下文中执行,msg.sender 和 msg.value 保持不变。这意味着合约可以在运行时从另一个地址动态加载代码。存储、当前地址和余额都指向调用合约,仅从被调用地址获取代码。这使 Solidity 能够实现“库”功能:可重用的代码库可以放置在合约存储中,例如用于实现复杂数据结构的库。

另一个相关的合约调用是调用指令集时使用 CREATE 指令。该命令将创建一个新合约并生成一个新地址。与创建以太坊唯一不同的是,波场新生成的地址使用了传入的智能合约交易id和被调用的nonce的哈希组合。与以太坊不同,这个 nonce 被定义为这个根调用创建的合约号。即如果CREATE指令有多次调用,从1开始,每次调用的合约按顺序编号。详情请参考代码。还需要注意的是,与deploycontract的grpc调用创建合约不同,CREATE的合约不会保存合约的abi。

1)TVM兼容solidity语言的转账形式,包括:
伴随constructor调用转账
伴随合约内函数调用转账
transfer/send/call/callcode/delegatecall函数调用转账
注意,波场的智能合约与波场系统合约的逻辑不同,如果转账的目标地址账户不存在,不能通过智能合约转账的形式创建目标地址账户。这也是与以太坊的不同点。
2)不同账户为超级节点投票 (Odyssey-v3.1.1及之后的版本暂时不支持)
3)超级节点获取所有奖励 (Odyssey-v3.1.1及之后的版本暂时不支持)
4)超级节点通过或否定提案 (Odyssey-v3.1.1及之后的版本暂时不支持)
5)超级节点提出提案 (Odyssey-v3.1.1及之后的版本暂时不支持)
6)超级节点删除提案 (Odyssey-v3.1.1及之后的版本暂时不支持)
7)波场byte地址转换为solidity地址 (Odyssey-v3.1.1及之后的版本暂时不支持)
8)波场string地址转换为solidity地址 (Odyssey-v3.1.1及之后的版本暂时不支持)
9)向目标账户地址发送token转账 (Odyssey-v3.1.1及之后的版本暂时不支持)
10)查询目标账户地址的指定token的数量 (Odyssey-v3.1.1及之后的版本暂时不支持)
11)兼容所有以太坊内置函数

注意:TRON2)- 10)是TRON自带的函数。中文文档请参考:中文文档/Virtual Machine/Virtual Machine Built-in Function.md

不推荐使用以太坊 RIPEMD160 功能。 TRON 返回基于 sha256 的哈希结果,这不是确切的以太坊 RIPEMD160。以后会考虑去掉这个功能。

3.solidity语言中合约地址的使用

以太坊虚拟机地址为20字节,波场虚拟机解析地址为21字节。 * 地址翻译

在solidity中使用时,需要对TRON地址进行如下处理(推荐):

/**
  *  @dev    convert uint256 (HexString add 0x at beginning) tron address to solidity address type
  *  @param  tronAddress uint256 tronAddress, begin with 0x, followed by HexString
  *  @return Solidity address type
  */
    function convertFromTronInt(uint256 tronAddress) public view returns(address){
        return address(tronAddress);
    }

这与以太坊中任何其他类型的地址类型相同。

Solidity 有地址不断的判断。如果你写一个21字节的地址,编译器会报错。只需要写一个20字节的地址,如:

function compareAddress(address tronAddress) public view returns (uint256){
        // if (tronAddress == 0x41ca35b7d915458ef540ade6068dfe2f44e8fa733c) { // compile error
        if (tronAddress == 0xca35b7d915458ef540ade6068dfe2f44e8fa733c) { // right
            return 1;
        } else {
            return 0;
        }
    }

当tronAddress为0000000000000000000041ca35b7d915458ef540ade6068dfe2f44e8fa733c,即来自wallet-cli的21字节地址时,会返回1,即正常TRON地址,判断正确。

Solidity 有地址常量的赋值。如果你写一个21字节的地址,编译器会报错。你只需要写一个 20 字节的地址。 solidity 中的后续操作直接使用这个 20 位地址。补码操作完成。例如:

function assignAddress() public view {
        // address newAddress = 0x41ca35b7d915458ef540ade6068dfe2f44e8fa733c; // compile error
        address newAddress = 0xca35b7d915458ef540ade6068dfe2f44e8fa733c;
        // do something
    }

如果要直接使用string类型的TRON地址(如TLLM21wteSPs4hKjbxgmH1L6poyMjeTbHm),请参考内置函数的两种地址转换方法(见II-4-7、II-4-8)@ >.

4.不同于以太坊的特殊恒定货币

类似于solidity对ether的支持,波场虚拟机代码支持的货币单位是trx和sun,其中1trx = 1000000 sun,区分大小写,只支持小写。目前,tron-studio 支持 trx 和 sun。在混音中,不支持 trx 和 sun。如果使用ether、finney等单位,请注意转换(可能会出现溢出错误)。我们建议使用 tron-studio 而不是 remix 来编写 tron 智能合约。

方块相关