まえがき
コントラクトをデプロイする際にcontract addressを取得せず、transaction hashだけすぐに欲しい場合に困ったのでメモ
詳しくはこちらを参照
コントラクト
いくつかの引数をコンストラクタに持ったコントラクトを作成
pragma solidity ^0.4.23;
contract Sunday {
uint public uint_;
string public string_;
bool public bool_;
address public address_;
uint[] public uintArr_;
constructor(uint _uint,string _string,bool _bool,address _address,uint[] _uintArr) public {
uint_ = _uint;
string_ = _string;
bool_ = _bool;
address_ = _address;
uintArr_ = _uintArr;
}
}
コントラクトのコンパイル
// 必要なパッケージをインポート
const solc = require('solc');
const Web3 = require('web3');
// web3の初期化
const web3 = new Web3();
// ネットワークと接続
web3.setProvider(new web3.providers.HttpProvider('http://localhost:8545'));
// コントラクトの読込
let source = // 上記のコントラクトコード
// コンパイル
let contract = solc.compile(source, 1);
引数の値について
type | value | example |
---|---|---|
uint | 123 | 000000000000000000000000000000000000000000000000000000000000007b |
string | test | 00000000000000000000000000000000000000000000000000000000000000a0(offset) & 0000000000000000000000000000000000000000000000000000000000000003 + 6162630000000000000000000000000000000000000000000000000000000000 |
boolean | true | 0000000000000000000000000000000000000000000000000000000000000001 |
address | 0xca35b7d915458ef540ade6068dfe2f44e8fa733c | 000000000000000000000000ca35b7d915458ef540ade6068dfe2f44e8fa733c |
uint[] | [123,234,345] | 00000000000000000000000000000000000000000000000000000000000000e0(offset) & 0000000000000000000000000000000000000000000000000000000000000003 + 000000000000000000000000000000000000000000000000000000000000007b + 00000000000000000000000000000000000000000000000000000000000000ea + 0000000000000000000000000000000000000000000000000000000000000159 |
デプロイコード
// コントラクトコンパイルの続き
// 引数一覧
let uint = 123;
let string = 'abc';
let bool = true;
let address = '0xca35b7d915458ef540ade6068dfe2f44e8fa733c';
let uintArr = [123,234,345];
// 第1引数のuint
let uintHex = web3.toHex(uint) // 値をHexへ変換
let uintValue = uintHex.slice(2) // 先頭の0xを削除
let uintResult = '0'.repeat(64 - uintValue.length) + uintValue // 左側を0で埋めて合計64文字(32byte)にする
// 第2引数のoffsetを取得
let offset1 = web3.toHex(5 * 32) // offsetの計算方法は省略
let offset1Value = offset1.slice(2) // 先頭の0xを削除
let offset1Result = '0'.repeat(64 - offset1Value.length) + offset1Value // 左側を0で埋めて合計64文字(32byte)にする
// 第3引数のboolean
let flg = bool ? 1 : 0
let booleanHex = web3.toHex(flg) // 値をHexへ変換
let booleanValue = booleanHex.slice(2) // 先頭の0xを削除
let booleanResult = '0'.repeat(64 - booleanValue.length) + booleanValue // 右側を0で埋めて合計64文字(32byte)にする
// 第4引数のaddress
let addressValue = address.slice(2) // 先頭の0xを削除
let addressResult = '0'.repeat(64 - addressValue.length) + addressValue // 左側を0で埋めて合計64文字(32byte)にする
// 第5引数のoffsetを取得
let offset2 = web3.toHex((5 + 2) * 32) // offsetの計算方法は省略
let offset2Value = offset2.slice(2) // 先頭の0xを削除
let offset2Result = '0'.repeat(64 - offset2Value.length) + offset2Value // 左側を0で埋めて合計64文字(32byte)にする
// 第2引数のstring
let stringHex = web3.toHex(string) // 値をHexへ変換
let stringValue = intHex.slice(2) // 先頭の0xを削除
let stringResult = stringValue + '0'.repeat(64 - stringValue.length) // 右側を0で埋めて合計64文字(32byte)にする
// 第5引数のuint[]
let uintCount = uintArr.length
let uintArrValue = uintArr.map((item)=>{
let itemHex = web3.toHex(item) // 値をHexへ変換
let itemValue = itemHex.slice(2) // 先頭の0xを削除
let itemResult = '0'.repeat(64 - itemValue.length) + itemValue // 左側を0で埋めて合計64文字(32byte)にする
return itemResult
})
let uintArrResult = '0'.repeat(64 - web3.toHex(uintCount).length) + web3.toHex(uintCount) + uintArrValue.join(''))
デプロイ
let _data = contract.bytecode +
uintResult +
offset1Result +
booleanResult +
addressResult +
offset2Result +
stringResult +
uintArrResult
// 推奨ガス値取得
let _gas = web3.eth.estimateGas(_data)
// 平均ガスプライス取得
let _gasPrice = web3.eth.gasPrice
// トランザクション送出 戻り値はトランザクションハッシュ
let transaction = web3.eth.sendTransaction({
from:_from, // coinbase等トランザクション発行主を指定
// to:_to, // 今回は使用せず
gas:_gas, // 適当な値を指定
gasPrice:_gasPrice, // 適当な値を指定
data:_data, // コントラクトのデプロイbytecode + コンストラクタの引数のHex値
// value:_value, // 今回は使用せず
nonce:_nonce // 適当な値を指定
})
_dataの中身
見やすいように32bytes毎に区切ってます
0x... // ここにはコントラクトのbytecodeが入る。長すぎるので省略
000000000000000000000000000000000000000000000000000000000000007b // 第1引数 123
00000000000000000000000000000000000000000000000000000000000000a0 // 第2引数のoffset
0000000000000000000000000000000000000000000000000000000000000001 // 第3引数 true
000000000000000000000000ca35b7d915458ef540ade6068dfe2f44e8fa733c // 第4引数 0xca35b7d915458ef540ade6068dfe2f44e8fa733c
00000000000000000000000000000000000000000000000000000000000000e0 // 第5引数のoffset
0000000000000000000000000000000000000000000000000000000000000003 // 第2引数の文字数
6162630000000000000000000000000000000000000000000000000000000000 // 第2引数のHex値
0000000000000000000000000000000000000000000000000000000000000003 // 第5引数の配列の要素数
000000000000000000000000000000000000000000000000000000000000007b // 第5引数の配列[0]のHex値
00000000000000000000000000000000000000000000000000000000000000ea // 第5引数の配列[1]のHex値
0000000000000000000000000000000000000000000000000000000000000159 // 第5引数の配列[2]のHex値
あとがき
駆け足でしたが以上。