# Solidity 进阶

## 单位 - unit

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

另外还有时间单位 `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))), ...)`
```

### 错误处理

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

### 数学和加密函数

```javascript
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

```javascript
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

合约的 `transfer` ， `create` ，及 `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 对合约创建合约的支持还不够完善。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://andelf.gitbook.io/tron/smart-contract/solidity-in-depth.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
