Solidity 进阶

这里介绍 Solidity 的进阶概念。

单位 - unit

Solidity 引入了单位的概念,TVM 对以太坊 EVM 做了相关修改。所以合约里可以轻松进行 trxsun 的换算。

另外还有时间单位 seconds, minutes, hours, days, weeks. 基础单位是 seconds.

全局变量/全局函数

是合约代码编写过程中可用的函数和常量。

参考: https://solidity.readthedocs.io/en/v0.6.6/units-and-global-variables.html

Block 及 Transaction 处理

// 为兼容提供,在 TVM 中无具体意义
block.difficulty (uint): current block difficulty
gasleft() returns (uint256): remaining gas
block.gaslimit (uint): current block gaslimit
tx.gasprice (uint): gas price of the transaction
blockhash(uint blockNumber) returns (bytes32): hash of the given block - only works for 256 most recent, excluding current, blocks
block.coinbase (address payable): current block miner’s address
block.number (uint): current block number
block.timestamp (uint): current block timestamp as seconds since unix epoch
msg.data (bytes calldata): complete calldata
msg.sender (address payable): sender of the message (current call)
msg.sig (bytes4): first four bytes of the calldata (i.e. function identifier)
msg.value (uint): number of wei sent with the message
msg.tokenvalue (uint): TRC10 token value
msg.tokenid (trcToken): TRC10 token 10
now (uint): current block timestamp (alias for block.timestamp)
tx.origin (address payable): sender of the transaction (full call chain)

address 成员函数

<address>.balance -> (uint256)
<address>.tokenBalance(trcToken) -> (uint)
<address payable>.transfer(uint256 amount)
<address payable>.transferToken(uint, trcToken)
.call()
.delegatecall()
.staticcall()

ABI Encoding and Decoding Functions

abi.decode(bytes memory encodedData, (...)) returns (...): ABI-decodes the given data, while the types are given in parentheses as second argument. Example: (uint a, uint[2] memory b, bytes memory c) = abi.decode(data, (uint, uint[2], bytes))
abi.encode(...) returns (bytes memory): ABI-encodes the given arguments
abi.encodePacked(...) returns (bytes memory): Performs packed encoding of the given arguments. Note that packed encoding can be ambiguous!
abi.encodeWithSelector(bytes4 selector, ...) returns (bytes memory): ABI-encodes the given arguments starting from the second and prepends the given four-byte selector
abi.encodeWithSignature(string memory signature, ...) returns (bytes memory): Equivalent to abi.encodeWithSelector(bytes4(keccak256(bytes(signature))), ...)`

错误处理

assert(bool condition)
require(bool condition)
require(bool condition, string memory message)
revert()
revert(string memory reason)

数学和加密函数

addmod(uint x, uint y, uint k) returns (uint)
> (x + y) % k
mulmod(uint x, uint y, uint k) returns (uint)
> (x * y) % k
keccak256(bytes memory) returns (bytes32)
sha256(bytes memory) returns (bytes32)
ripemd160(bytes memory) returns (bytes20)
ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) returns (address)
> 注意,`v` 未处理

内联汇编 - assembly

assembly {
// retrieve the size of the code, this needs assembly
let size := extcodesize(_addr)
// allocate output byte array - this could also be done without assembly
// by using o_code = new bytes(size)
o_code := mload(0x40)
// new "memory end" including padding
mstore(0x40, add(o_code, and(add(add(size, 0x20), 0x1f), not(0x1f))))
// store length in memory
mstore(o_code, size)
// actually retrieve the code, this needs assembly
extcodecopy(_addr, add(o_code, 0x20), 0, size)
}

内部交易 - inline transaction / internal transaction

合约的 transfercreate ,及 call, suicide 调用,会生成内部交易。

其定义是:

message InternalTransaction {
// internalTransaction identity, the root InternalTransaction hash
// should equals to root transaction id.
bytes hash = 1;
// the one send trx (TBD: or token) via function
bytes caller_address = 2;
// the one recieve trx (TBD: or token) via function
bytes transferTo_address = 3;
message CallValueInfo {
// trx (TBD: or token) value
int64 callValue = 1;
// TBD: tokenName, trx should be empty
string tokenId = 2;
}
repeated CallValueInfo callValueInfo = 4;
bytes note = 5;
bool rejected = 6;
}

目前 TRON 对合约创建合约的支持还不够完善。