Skip to content

Instantly share code, notes, and snippets.

@ricmoo
Created March 8, 2018 21:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ricmoo/e38d4d71dff7156033922d2e5de88d38 to your computer and use it in GitHub Desktop.
Save ricmoo/e38d4d71dff7156033922d2e5de88d38 to your computer and use it in GitHub Desktop.
Solidity ABIv2: A Foray into the Experimental
'use strict';
var fs = require('fs');
var ethers = require('ethers');
var solc = require('solc');
var provider = ethers.providers.getDefaultProvider('ropsten');
var wallet = new ethers.Wallet(fs.readFileSync('account.key').toString().trim(), provider);
var result = {
deployer: wallet.address,
source: fs.readFileSync('./UserDirectory.sol').toString(),
optimize: 1,
timestamp: (new Date()).getTime(),
};
var contracts = solc.compile(result.source, result.optimize);
if (contracts.errors && contracts.errors.length) {
console.log('Errors:');
contracts.errors.forEach(function(error) {
console.log(' ' + error);
});
}
var code = contracts.contracts[':UserDirectory'];
result.bytecode = '0x' + code.bytecode;
result.compiler = JSON.parse(code.metadata).compiler.version;
result.functionHashes = code.functionHashes;
result.interface = code.interface;
result.runtimeBytecode = '0x' + code.runtimeBytecode;
var deployTransaction = ethers.Contract.getDeployTransaction(result.bytecode, result.interface);
deployTransaction.gasLimit = 1500000;
deployTransaction.gasPrice = 10000000000;
wallet.sendTransaction(deployTransaction).then(function(tx) {
result.transactionHash = tx.hash;
result.contractAddress = ethers.utils.getContractAddress(tx);
tx.wait().then(function(tx) {
result.blockHash = tx.blockHash;
result.blockNumber = tx.blockNumber;
var data = JSON.stringify(result, undefined, ' ');
fs.writeFileSync('UserDirectory.json', data);
console.log(data);
});
});
'use strict';
var fs = require('fs');
var ethers = require('ethers');
var provider = ethers.providers.getDefaultProvider('ropsten');
var privateKey = fs.readFileSync('account.key').toString().trim();
var walletAdmin = new ethers.Wallet(privateKey, provider);
var walletUser = new ethers.Wallet('0x0123456789012345678901234567890123456789012345678901234567895555', provider);
var data = require('./UserDirectory.json');
var contract = new ethers.Contract(data.contractAddress, data.interface, walletAdmin);
console.log(contract);
contract.onuseradded = function(address, user) {
console.log(user);
// {
// name: "Rick Sanchez",
// addr: "0xCB00CDE33a7a0Fba30C63745534F1f7Ae607076b"
// contact: {
// email: "rick.c137@citadel.cfc",
// phone: "+1 (555) 314-1593",
// }
// }
};
contract.onuserupdated = function(address, user) {
console.log(address);
console.log(user);
};
var user = {
name: 'Rick Sanchez',
addr: '0xCB00CDE33a7a0Fba30C63745534F1f7Ae607076b',
contact: {
email: 'rick.c137@citadel.cfc',
phone: '+1 (555) 314-1593'
}
};
contract.addUser(user).then(function(tx) {
console.log(tx);
});
contract.user(user.addr).then(function(user) {
console.log(user);
});
console.log(data.contractAddress, data.interface, walletUser);
var contract = new ethers.Contract(data.contractAddress, data.interface, walletUser);
var contact = {
email: 'rick.c137@tinyplanet.cfc',
phone: '+1 (555) 314-1593'
};
contract.update(contact).then(function(tx) {
console.log(tx);
});
{
"deployer": "0xD7DE6d5514c0bfA85c7b8018FBBd9914583Ce486",
"source": "pragma solidity ^0.4.20;\npragma experimental ABIEncoderV2;\n\ncontract UserDirectory {\n\n struct Contact {\n string email;\n string phone;\n }\n\n struct User {\n string name;\n address addr;\n Contact contact;\n }\n\n address _admin;\n mapping (address => User) _users;\n\n event UserAdded(address indexed addr, User user);\n event UserUpdated(address indexed addr, User user);\n\n function UserDirectory() {\n _admin = msg.sender;\n }\n\n // Only the admin can add users\n function addUser(User user) {\n require(msg.sender == _admin);\n _users[user.addr] = user;\n UserAdded(user.addr, user);\n }\n\n // Let any user update their contact info\n function update(Contact contact) {\n User storage user = _users[msg.sender];\n require(user.addr != 0);\n user.contact = contact;\n UserUpdated(user.addr, user);\n }\n\n function user(address addr) constant returns (User user) {\n return _users[addr];\n }\n}\n",
"optimize": 1,
"timestamp": 1520200376714,
"bytecode": "0x6060604052341561000f57600080fd5b60008054600160a060020a033316600160a060020a0319909116179055610a9c8061003b6000396000f3006060604052600436106100565763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416632cf79d61811461005b5780633d7048b31461007b57806381e7e20e14610099575b600080fd5b341561006657600080fd5b610079610074366004610754565b6100cd565b005b341561008657600080fd5b610079610094366004610789565b61017b565b34156100a457600080fd5b6100b76100b236600461072e565b610288565b6040516100c49190610985565b60405180910390f35b600160a060020a0333811660009081526001602081905260409091209081015490911615156100fb57600080fd5b81600282018151819080516101149291602001906104cc565b5060208201518160010190805161012f9291602001906104cc565b5050506001810154600160a060020a03167fe18472c463dadd4f49817554190c36c9c7c3ee58e4207fc7f3fc36f4a4e4b8a88260405161016f9190610996565b60405180910390a25050565b60005433600160a060020a0390811691161461019657600080fd5b80600160008360200151600160a060020a0316815260208101919091526040016000208151819080516101cd9291602001906104cc565b50602082015160018201805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a039290921691909117905560408201516002820181518190805161021f9291602001906104cc565b5060208201518160010190805161023a9291602001906104cc565b5050509050508060200151600160a060020a03167f5a8b3b2720d1455096b140bf30eb96fd241659b4b6c05c59eeb2516e4755c1518260405161027d9190610985565b60405180910390a250565b61029061054a565b600160a060020a0382166000908152600160205260409081902090606090519081016040529081600082018054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561034f5780601f106103245761010080835404028352916020019161034f565b820191906000526020600020905b81548152906001019060200180831161033257829003601f168201915b50505091835250506001820154600160a060020a03166020820152604090810190600283019080519081016040529081600082018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156104175780601f106103ec57610100808354040283529160200191610417565b820191906000526020600020905b8154815290600101906020018083116103fa57829003601f168201915b50505050508152602001600182018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156104b95780601f1061048e576101008083540402835291602001916104b9565b820191906000526020600020905b81548152906001019060200180831161049c57829003601f168201915b5050509190925250505090525092915050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061050d57805160ff191683800117855561053a565b8280016001018555821561053a579182015b8281111561053a57825182559160200191906001019061051f565b50610546929150610577565b5090565b60806040519081016040528061055e610594565b8152600060208201526040016105726105a6565b905290565b61059191905b80821115610546576000815560010161057d565b90565b60206040519081016040526000815290565b60408051908101604052806105b9610594565b8152602001610572610594565b60006105d28235610a10565b9392505050565b6000601f82018390126105eb57600080fd5b81356105fe6105f9826109d2565b6109a7565b9150808252602083016020830185838301111561061a57600080fd5b610625838284610a1c565b50505092915050565b60006040828403121561064057600080fd5b61064a60406109a7565b9050813567ffffffffffffffff81111561066357600080fd5b61066f848285016105d9565b825250602082013567ffffffffffffffff81111561068c57600080fd5b610698848285016105d9565b60208301525092915050565b6000606082840312156106b657600080fd5b6106c060606109a7565b9050813567ffffffffffffffff8111156106d957600080fd5b6106e5848285016105d9565b82525060206106f6848483016105c6565b602083015250604082013567ffffffffffffffff81111561071657600080fd5b6107228482850161062e565b60408301525092915050565b60006020828403121561074057600080fd5b600061074c84846105c6565b949350505050565b60006020828403121561076657600080fd5b813567ffffffffffffffff81111561077d57600080fd5b61074c8482850161062e565b60006020828403121561079b57600080fd5b813567ffffffffffffffff8111156107b257600080fd5b61074c848285016106a4565b6107c781610a10565b82525050565b60006107d882610a06565b8084526107ec816020860160208601610a28565b6107f581610a58565b9093016020019392505050565b60008154600181166000811461081f576001811461083d57610879565b60028204607f16855260ff1982166020860152604085019250610879565b60028204808652602086019550610853856109fa565b60005b8281101561087257815488820152600190910190602001610856565b8701945050505b505092915050565b6000604083018251848203855261089882826107cd565b915050602083015184820360208601526108b282826107cd565b95945050505050565b6040808352600090830181836108d18382610802565b9250506001840185830360208701526108ea8382610802565b9695505050505050565b6000606083018251848203855261090b82826107cd565b915050602083015161092060208601826107be565b50604083015184820360408601526108b28282610881565b60608083526000908301818361094e8382610802565b9250506001840154905061096181610591565b61096e60208701826107be565b506002840185830360408701526108ea83826108bb565b602080825281016105d281846108f4565b602080825281016105d28184610938565b6000604051905081810181811067ffffffffffffffff821117156109ca57600080fd5b604052919050565b600067ffffffffffffffff8211156109e957600080fd5b506020601f91909101601f19160190565b60009081526020902090565b6000815192915050565b600160a060020a031690565b82818337506000910152565b60005b83811015610a43578082015183820152602001610a2b565b83811115610a52576000848401525b50505050565b601f01601f1916905600a265627a7a72305820567b389796b04bff1b10e351702043761b20dc3c87faf0b2f18dfe0e6c76592c6c6578706572696d656e74616cf50037",
"compiler": "0.4.20+commit.3155dd80",
"functionHashes": {
"addUser((string,address,(string,string)))": "3d7048b3",
"update((string,string))": "2cf79d61",
"user(address)": "81e7e20e"
},
"interface": "[{\"constant\":false,\"inputs\":[{\"components\":[{\"name\":\"email\",\"type\":\"string\"},{\"name\":\"phone\",\"type\":\"string\"}],\"name\":\"contact\",\"type\":\"tuple\"}],\"name\":\"update\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"components\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"addr\",\"type\":\"address\"},{\"components\":[{\"name\":\"email\",\"type\":\"string\"},{\"name\":\"phone\",\"type\":\"string\"}],\"name\":\"contact\",\"type\":\"tuple\"}],\"name\":\"user\",\"type\":\"tuple\"}],\"name\":\"addUser\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"addr\",\"type\":\"address\"}],\"name\":\"user\",\"outputs\":[{\"components\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"addr\",\"type\":\"address\"},{\"components\":[{\"name\":\"email\",\"type\":\"string\"},{\"name\":\"phone\",\"type\":\"string\"}],\"name\":\"contact\",\"type\":\"tuple\"}],\"name\":\"user\",\"type\":\"tuple\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"addr\",\"type\":\"address\"},{\"components\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"addr\",\"type\":\"address\"},{\"components\":[{\"name\":\"email\",\"type\":\"string\"},{\"name\":\"phone\",\"type\":\"string\"}],\"name\":\"contact\",\"type\":\"tuple\"}],\"indexed\":false,\"name\":\"user\",\"type\":\"tuple\"}],\"name\":\"UserAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"addr\",\"type\":\"address\"},{\"components\":[{\"name\":\"name\",\"type\":\"string\"},{\"name\":\"addr\",\"type\":\"address\"},{\"components\":[{\"name\":\"email\",\"type\":\"string\"},{\"name\":\"phone\",\"type\":\"string\"}],\"name\":\"contact\",\"type\":\"tuple\"}],\"indexed\":false,\"name\":\"user\",\"type\":\"tuple\"}],\"name\":\"UserUpdated\",\"type\":\"event\"}]",
"runtimeBytecode": "0x6060604052600436106100565763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416632cf79d61811461005b5780633d7048b31461007b57806381e7e20e14610099575b600080fd5b341561006657600080fd5b610079610074366004610754565b6100cd565b005b341561008657600080fd5b610079610094366004610789565b61017b565b34156100a457600080fd5b6100b76100b236600461072e565b610288565b6040516100c49190610985565b60405180910390f35b600160a060020a0333811660009081526001602081905260409091209081015490911615156100fb57600080fd5b81600282018151819080516101149291602001906104cc565b5060208201518160010190805161012f9291602001906104cc565b5050506001810154600160a060020a03167fe18472c463dadd4f49817554190c36c9c7c3ee58e4207fc7f3fc36f4a4e4b8a88260405161016f9190610996565b60405180910390a25050565b60005433600160a060020a0390811691161461019657600080fd5b80600160008360200151600160a060020a0316815260208101919091526040016000208151819080516101cd9291602001906104cc565b50602082015160018201805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a039290921691909117905560408201516002820181518190805161021f9291602001906104cc565b5060208201518160010190805161023a9291602001906104cc565b5050509050508060200151600160a060020a03167f5a8b3b2720d1455096b140bf30eb96fd241659b4b6c05c59eeb2516e4755c1518260405161027d9190610985565b60405180910390a250565b61029061054a565b600160a060020a0382166000908152600160205260409081902090606090519081016040529081600082018054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561034f5780601f106103245761010080835404028352916020019161034f565b820191906000526020600020905b81548152906001019060200180831161033257829003601f168201915b50505091835250506001820154600160a060020a03166020820152604090810190600283019080519081016040529081600082018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156104175780601f106103ec57610100808354040283529160200191610417565b820191906000526020600020905b8154815290600101906020018083116103fa57829003601f168201915b50505050508152602001600182018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156104b95780601f1061048e576101008083540402835291602001916104b9565b820191906000526020600020905b81548152906001019060200180831161049c57829003601f168201915b5050509190925250505090525092915050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061050d57805160ff191683800117855561053a565b8280016001018555821561053a579182015b8281111561053a57825182559160200191906001019061051f565b50610546929150610577565b5090565b60806040519081016040528061055e610594565b8152600060208201526040016105726105a6565b905290565b61059191905b80821115610546576000815560010161057d565b90565b60206040519081016040526000815290565b60408051908101604052806105b9610594565b8152602001610572610594565b60006105d28235610a10565b9392505050565b6000601f82018390126105eb57600080fd5b81356105fe6105f9826109d2565b6109a7565b9150808252602083016020830185838301111561061a57600080fd5b610625838284610a1c565b50505092915050565b60006040828403121561064057600080fd5b61064a60406109a7565b9050813567ffffffffffffffff81111561066357600080fd5b61066f848285016105d9565b825250602082013567ffffffffffffffff81111561068c57600080fd5b610698848285016105d9565b60208301525092915050565b6000606082840312156106b657600080fd5b6106c060606109a7565b9050813567ffffffffffffffff8111156106d957600080fd5b6106e5848285016105d9565b82525060206106f6848483016105c6565b602083015250604082013567ffffffffffffffff81111561071657600080fd5b6107228482850161062e565b60408301525092915050565b60006020828403121561074057600080fd5b600061074c84846105c6565b949350505050565b60006020828403121561076657600080fd5b813567ffffffffffffffff81111561077d57600080fd5b61074c8482850161062e565b60006020828403121561079b57600080fd5b813567ffffffffffffffff8111156107b257600080fd5b61074c848285016106a4565b6107c781610a10565b82525050565b60006107d882610a06565b8084526107ec816020860160208601610a28565b6107f581610a58565b9093016020019392505050565b60008154600181166000811461081f576001811461083d57610879565b60028204607f16855260ff1982166020860152604085019250610879565b60028204808652602086019550610853856109fa565b60005b8281101561087257815488820152600190910190602001610856565b8701945050505b505092915050565b6000604083018251848203855261089882826107cd565b915050602083015184820360208601526108b282826107cd565b95945050505050565b6040808352600090830181836108d18382610802565b9250506001840185830360208701526108ea8382610802565b9695505050505050565b6000606083018251848203855261090b82826107cd565b915050602083015161092060208601826107be565b50604083015184820360408601526108b28282610881565b60608083526000908301818361094e8382610802565b9250506001840154905061096181610591565b61096e60208701826107be565b506002840185830360408701526108ea83826108bb565b602080825281016105d281846108f4565b602080825281016105d28184610938565b6000604051905081810181811067ffffffffffffffff821117156109ca57600080fd5b604052919050565b600067ffffffffffffffff8211156109e957600080fd5b506020601f91909101601f19160190565b60009081526020902090565b6000815192915050565b600160a060020a031690565b82818337506000910152565b60005b83811015610a43578082015183820152602001610a2b565b83811115610a52576000848401525b50505050565b601f01601f1916905600a265627a7a72305820567b389796b04bff1b10e351702043761b20dc3c87faf0b2f18dfe0e6c76592c6c6578706572696d656e74616cf50037",
"transactionHash": "0x532437cf980a670175d78cd3f579f0ed40d21b2a1ae13f15ac52613d6d9857dd",
"contractAddress": "0xd2d98e1F10F31E5e83c8b1443Df69cf70f90467b",
"blockHash": "0x728da858195852b6f72c14ff628529058e87300dab4c4584c3bd94f70518eedc",
"blockNumber": 2770685
}
pragma solidity ^0.4.20;
pragma experimental ABIEncoderV2;
contract UserDirectory {
struct Contact {
string email;
string phone;
}
struct User {
string name;
address addr;
Contact contact;
}
address _admin;
mapping (address => User) _users;
event UserAdded(address indexed addr, User user);
event UserUpdated(address indexed addr, User user);
function UserDirectory() public {
_admin = msg.sender;
}
// Only the admin can add users
function addUser(User user) public {
require(msg.sender == _admin);
_users[user.addr] = user;
UserAdded(user.addr, user);
}
// Let any user update their contact info
function update(Contact contact) public {
User storage user = _users[msg.sender];
require(user.addr != 0);
user.contact = contact;
UserUpdated(user.addr, user);
}
function user(address addr) constant returns (User user) public {
return _users[addr];
}
}
@ricmoo
Copy link
Author

ricmoo commented Mar 8, 2018

Here are all the files used to create the Solidity ABIv2: A Foray into the Experimental Medium post.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment