solidity学習プロセス---abi符号化
5870 ワード
abi符号化関数
abiとは
アプリケーションバイナリインタフェース、イーサー坊の呼び出し契約時のインタフェースはABIが2つのプログラムモジュール間のインタフェースであることを示し、主にデータをソースコードとして符号化または復号するために使用されるコードである.イーサー坊で主にsolidity契約の関数呼び出しに用いられ,データの読み出しを逆符号化する方法
solidityABI符号化関数
solidityABI符号化関数実装の詳細
関数セレクタ.公式ドキュメントでは、1つの関数呼び出しデータの最初の4バイトを定義し、呼び出す関数を指定します.これがある関数署名のKeccak(SHA-3)ハッシュの上位4バイト(上位左の大端順)である(訳注:ここで「上位左の大端順」とは、最上位バイトが最下位アドレスに格納されるシリアル化符号化方式、すなわち、上位バイトが左である). この署名は、関数名にカッコで囲まれたパラメータタイプのリストを加えたベースプロトタイプの仕様表現として定義され、パラメータタイプ間はカンマで区切られ、スペースはありません.
簡単に言えば、関数セレクタは、関数名によってパラメータを識別し、異なる契約間の関数呼び出しに使用できます.
1.契約における関数呼び出し呼び出し呼び出し呼び出しデータの最初の4バイト(0 x以降)は、関数名およびパラメータタイプを署名処理(Keccak–Sha 3)することである.
solidityABI符号化関数実装:
contract testABI {
uint storedData;
function set(uint x) public {
storedData = x;
}
function abiEncode() public view returns (bytes memory) {
abi.encode(1); // 1 ABI
return abi.encodeWithSignature("set(uint256)", 1); // set(uint256) 1 ABI
}
}
remix導入契約の後、abiEncode()を呼び出すと、次のデータ出力が生成されます.
0x60fe47b10000000000000000000000000000000000000000000000000000000000000015
[
{
"constant": false,
"inputs": [
{
"internalType": "uint256",
"name": "value",
"type": "uint256"
}
],
"name": "set",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
}
] ``
abiDetail:
abi.encodeとabi.encodePacked
contract TestDifference {
function testUint(
uint8 _num1,
uint32 _num2
)
public view returns (bytes memory, bytes memory) {
return (
abi.encode(_num1),
abi.encodePacked(_num2)
);
}
function testBytes() public view returns (bytes memory, bytes memory) {
bytes memory _bts ="Hello,world!";
return (abi.encodePacked(_bts),abi.encode(_bts));
}
}
abiの使用について.encodeWithSignature(string signature, …) returns (bytes)
主な適用シーン:関数呼び出しかんすうよびだし
contract Contract {
MyContract contract1 = new MyContract();
function getSelector() public view returns (bytes4, bytes4) {
return (contract1.function1.selector, contract1.getBalance.selector);
}
function callGetValue(uint _x) public view returns (uint) {
bytes4 selector = contract1.getValue.selector;
bytes memory data = abi.encodeWithSelector(selector, _x);
(bool success, bytes memory returnedData) = address(contract1).staticcall(data);
require(success);
return abi.decode(returnedData, (uint256));
}
}
contract MyContract {
function function1() public {}
function getBalance(address _address) public view returns (uint256){}
function getValue (uint _value) public pure returns (uint) {
return _value;
}
}