[Ethereum] contractのdeploy その2

sample_greeting.sol

contract SampleGreeting {
	string greeting = 'Hello World';

	function getGreet() public view returns (string memory){
		return greeting;
	}
}

$ sudo snap install solc
$ solc –bin –abi sample_greeting.sol
sample_greeting.sol:1:1: Warning: Source file does not specify required compiler version! Consider adding “pragma solidity ^0.5.16;”
contract SampleGreeting {
^ (Relevant source part starts here and spans across multiple lines).

======= sample_greeting.sol:SampleGreeting =======
Binary:
60806040526040518060400160405280600b81526020017f48656c6c6f20576f726c640000000000000000000000000000000000000000008152506000908051906020019061004f929190610062565b5034801561005c57600080fd5b50610107565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100a357805160ff19168380011785556100d1565b828001600101855582156100d1579182015b828111156100d05782518255916020019190600101906100b5565b5b5090506100de91906100e2565b5090565b61010491905b808211156101005760008160009055506001016100e8565b5090565b90565b61018a806101166000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063d705a4b514610030575b600080fd5b6100386100b3565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561007857808201518184015260208101905061005d565b50505050905090810190601f1680156100a55780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b606060008054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561014b5780601f106101205761010080835404028352916020019161014b565b820191906000526020600020905b81548152906001019060200180831161012e57829003601f168201915b505050505090509056fea265627a7a72315820be61e923cb4240e17bacc0ab36f4b2a0e91dd3c77c284e3edcc3bbcbc6e5079564736f6c63430005100032
Contract JSON ABI
[{“constant”:true,”inputs”:[],”name”:”getGreet”,”outputs”:[{“internalType”:”string”,”name”:””,”type”:”string”}],”payable”:false,”stateMutability”:”view”,”type”:”function”}]

const Web3 = require('web3');

const mnemonic = "*";

const HDWalletProvider = require('truffle-hdwallet-provider');
let provider = new HDWalletProvider(mnemonic, 'https://ropsten.infura.io/v3/*', 0, 1);

let web3 = new Web3(provider);

let bin = '0x60806040526040518060400160405280600b81526020017f48656c6c6f20576f726c640000000000000000000000000000000000000000008152506000908051906020019061004f929190610062565b5034801561005c57600080fd5b50610107565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100a357805160ff19168380011785556100d1565b828001600101855582156100d1579182015b828111156100d05782518255916020019190600101906100b5565b5b5090506100de91906100e2565b5090565b61010491905b808211156101005760008160009055506001016100e8565b5090565b90565b61018a806101166000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063d705a4b514610030575b600080fd5b6100386100b3565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561007857808201518184015260208101905061005d565b50505050905090810190601f1680156100a55780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b606060008054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561014b5780601f106101205761010080835404028352916020019161014b565b820191906000526020600020905b81548152906001019060200180831161012e57829003601f168201915b505050505090509056fea265627a7a72315820be61e923cb4240e17bacc0ab36f4b2a0e91dd3c77c284e3edcc3bbcbc6e5079564736f6c63430005100032';
let abi = [{"constant":true,"inputs":[],"name":"getGreet","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"}];
let data = {
	'data': bin
}

let contract = new web3.eth.Contract(abi, null, data);
console.log('contract:', contract);

$ node sample.js
///
_jsonInterface:
[ { constant: true,
inputs: [],
name: ‘getGreet’,
outputs: [Array],
payable: false,
stateMutability: ‘view’,
type: ‘function’,
signature: ‘*’ } ] }

signatureの値をメモしておく

web3.eth.getGasPrice().
	then((averageGasPrice) => {
		console.log("gasPrice: " + averageGasPrice);
	}).catch(console.error);

web3.eth.getAccounts((error, result) => {
	console.log('result: ', result);

	web3.eth.getTransactionCount(result[0], (error, response)=>{
		console.log('nonce:', response);
	})
})

contract.deploy().estimateGas().
	then((estimatedGas) => {
		console.log("gas: " + estimatedGas);
	}).catch(console.error);

$ node sample.js
result: [ ‘*’ ]
gasPrice: 1500000013
gas: 164431
nonce: 3

let sender_address = "*";
let nonce = '3';
let chainId = '3';
let gas = 164431;
let gasPrice = '1500000013'

let tx = {
  'from': sender_address,
  'nonce': nonce,
  'chainId': chainId,
  'gas': gas,
  'gasPrice': gasPrice,
  'data': bin,
}

const PRIVATE_KEY = "*";

web3.eth.accounts.signTransaction(tx, PRIVATE_KEY, (error, response)=>{
    console.log(response);
});

{ messageHash:
‘0x71d7*’,
v: ‘0x2a’,
r:
‘0xd04f9c44192de22c1088feccc*’,
s:
‘0x593a5ec5a50d1d5bed367*’,
rawTransaction:
‘0xf902f2038459682f0d8302824f8080b902a060806040526040518060400160405280600b81526020017f48656c6c6f20576f726c640000000000000000000000000000000000000000008152506000908051906020019061004f929190610062565b5034801561005c57600080fd5b50610107565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100a357805160ff19168380011785556100d1565b828001600101855582156100d1579182015b828111156100d05782518255916020019190600101906100b5565b5b5090506100de91906100e2565b5090565b61010491905b808211156101005760008160009055506001016100e8565b5090565b90565b61018a806101166000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063d705a4b514610030575b600080fd5b6100386100b3565b604051808060200182810*’,
transactionHash:
‘0x55a06ab424128b04b9002fe7de1a17e8981d94728bac06dd55993cfdba1b860d’ }

デプロイ

let raw = '0xf902f2038459682f0d8302824f8080b902a060806040526040518060400160405280600b81526020017f48656c6c6f20576f726c640000000000000000000000000000000000000000008152506000908051906020019061004f929190610062565b5034801561005c57600080fd5b50610107565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100a357805160ff19168380011785556100d1565b828001600101855582156100d1579182015b828111156100d05782518255916020019190600101906100b5565b5b5090506100de91906100e2565b5090565b61010491905b808211156101005760008160009055506001016100e8565b5090565b90565b61018a806101166000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063d705a4b514610030575b600080fd5b6100386100b3565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561007857808201518184015260208101905061005d565b50505050905090810190601f1680156100a5578082038051600183*';

web3.eth.sendSignedTransaction(raw).on('receipt', console.log);

$ node sample.js
{ blockHash:
‘0x8414d2fac3b36315828b7d330287a181e3b58ac29ee5d1325fb27b6d92dc03d1’,
blockNumber: 11682111,
contractAddress: ‘0x31695391C6C0f3A3F2EDe7cDb9B13Da277A8e2Eb’,
cumulativeGasUsed: 1680291,
effectiveGasPrice: ‘0x59682f0d’,
from: ‘0x71c9f1d5be00173ae7b774bdbe2112cdd03c5c92’,
gasUsed: 164431,
logs: [],
logsBloom:
‘0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000’,
status: true,
to: null,
transactionHash:
‘0x55a06ab424128b04b9002fe7de1a17e8981d94728bac06dd55993cfdba1b860d’,
transactionIndex: 13,
type: ‘0x0’ }

web3.eth.getAccounts((error, result)=> {
	let sender_address = result[0]
	let call_data = {
		'from': sender_address,
		'to': recipient_address,
		'data': signature
	}

	web3.eth.call(call_data, (error, response) => {
		console.log('response: ', response);
		provider.engine.stop();
	})
})

$ node sample.js
response: 0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000b48656c6c6f20576f726c64000000000000000000000000000000000000000000

おおおお なるほど
solidityでcompileしたデータを、from, nonce, chainId, gas, gasPriceなどと一緒にトランザクションにして秘密鍵で署名してデプロイしてるのね。

一連の流れはわかった!