Using Embark default ERC20Token, and changed way to determine if contract instance is valid

This commit is contained in:
Richard Ramos 2018-04-25 14:49:13 -04:00
parent 6c90a57cad
commit dd262752c2
13 changed files with 2244 additions and 303 deletions

View File

@ -1,272 +0,0 @@
[
{
"constant": true,
"inputs": [],
"name": "name",
"outputs": [
{
"name": "",
"type": "string"
}
],
"payable": false,
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_spender",
"type": "address"
},
{
"name": "_value",
"type": "uint256"
}
],
"name": "approve",
"outputs": [
{
"name": "success",
"type": "bool"
}
],
"payable": false,
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "totalSupply",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_from",
"type": "address"
},
{
"name": "_to",
"type": "address"
},
{
"name": "_value",
"type": "uint256"
}
],
"name": "transferFrom",
"outputs": [
{
"name": "success",
"type": "bool"
}
],
"payable": false,
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "decimals",
"outputs": [
{
"name": "",
"type": "uint8"
}
],
"payable": false,
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "version",
"outputs": [
{
"name": "",
"type": "string"
}
],
"payable": false,
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "_owner",
"type": "address"
}
],
"name": "balanceOf",
"outputs": [
{
"name": "balance",
"type": "uint256"
}
],
"payable": false,
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "symbol",
"outputs": [
{
"name": "",
"type": "string"
}
],
"payable": false,
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_to",
"type": "address"
},
{
"name": "_value",
"type": "uint256"
}
],
"name": "transfer",
"outputs": [
{
"name": "success",
"type": "bool"
}
],
"payable": false,
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_spender",
"type": "address"
},
{
"name": "_value",
"type": "uint256"
},
{
"name": "_extraData",
"type": "bytes"
}
],
"name": "approveAndCall",
"outputs": [
{
"name": "success",
"type": "bool"
}
],
"payable": false,
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "_owner",
"type": "address"
},
{
"name": "_spender",
"type": "address"
}
],
"name": "allowance",
"outputs": [
{
"name": "remaining",
"type": "uint256"
}
],
"payable": false,
"type": "function"
},
{
"inputs": [
{
"name": "_initialAmount",
"type": "uint256"
},
{
"name": "_tokenName",
"type": "string"
},
{
"name": "_decimalUnits",
"type": "uint8"
},
{
"name": "_tokenSymbol",
"type": "string"
}
],
"type": "constructor"
},
{
"payable": false,
"type": "fallback"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "_from",
"type": "address"
},
{
"indexed": true,
"name": "_to",
"type": "address"
},
{
"indexed": false,
"name": "_value",
"type": "uint256"
}
],
"name": "Transfer",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "_owner",
"type": "address"
},
{
"indexed": true,
"name": "_spender",
"type": "address"
},
{
"indexed": false,
"name": "_value",
"type": "uint256"
}
],
"name": "Approval",
"type": "event"
}
]

View File

@ -0,0 +1,191 @@
{
"contract_name": "ERC20Token",
"code": "",
"runtime_bytecode": "",
"real_runtime_bytecode": "",
"swarm_hash": "",
"gas_estimates": null,
"function_hashes": {
"allowance(address,address)": "dd62ed3e",
"approve(address,uint256)": "095ea7b3",
"balanceOf(address)": "70a08231",
"totalSupply()": "18160ddd",
"transfer(address,uint256)": "a9059cbb",
"transferFrom(address,address,uint256)": "23b872dd"
},
"abi": [
{
"constant": false,
"inputs": [
{
"name": "_spender",
"type": "address"
},
{
"name": "_value",
"type": "uint256"
}
],
"name": "approve",
"outputs": [
{
"name": "success",
"type": "bool"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "totalSupply",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_from",
"type": "address"
},
{
"name": "_to",
"type": "address"
},
{
"name": "_value",
"type": "uint256"
}
],
"name": "transferFrom",
"outputs": [
{
"name": "success",
"type": "bool"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "_owner",
"type": "address"
}
],
"name": "balanceOf",
"outputs": [
{
"name": "balance",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_to",
"type": "address"
},
{
"name": "_value",
"type": "uint256"
}
],
"name": "transfer",
"outputs": [
{
"name": "success",
"type": "bool"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "_owner",
"type": "address"
},
{
"name": "_spender",
"type": "address"
}
],
"name": "allowance",
"outputs": [
{
"name": "remaining",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "_from",
"type": "address"
},
{
"indexed": true,
"name": "_to",
"type": "address"
},
{
"indexed": false,
"name": "_value",
"type": "uint256"
}
],
"name": "Transfer",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "_owner",
"type": "address"
},
{
"indexed": true,
"name": "_spender",
"type": "address"
},
{
"indexed": false,
"name": "_value",
"type": "uint256"
}
],
"name": "Approval",
"type": "event"
}
]
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -30,9 +30,10 @@
"contracts":{
"IdentityGasRelay": {
"abiFile": "../abi/IdentityGasRelay.json",
"isIdentity": true,
"factoryAddress": "0x18f71378f4735b35e01eb71afcc66df090eccea7",
"abiFile": "../abi/IdentityGasRelay.json",
"kernelVerification": "isKernel(address _addr)",
"allowedFunctions": [
{
"function": "approveAndCallGasRelayed(address,address,uint256,bytes,uint256,uint256,uint256,address,bytes)",
@ -58,9 +59,9 @@
]
},
"SNTController": {
"abiFile": "../abi/SNTController.json",
"isIdentity": false,
"address": "0x96f0811c6484c59c2674da1f64e725c01d82c1b5",
"abiFile": "../abi/SNTController.json",
"allowedFunctions": [
{
"function":"transferSNT(address,uint256,uint256,uint256,bytes)",

View File

@ -2,9 +2,10 @@
"name": "gas-relayer",
"version": "0.0.1",
"description": "Gas relayer to avoid having to hold ether to perform transactions when you already have a token",
"main": "index.js",
"main": "src/service.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node src/service.js"
},
"author": "",
"license": "ISC",

View File

@ -11,8 +11,6 @@ class ContractSettings {
this.events = eventEmitter;
this.pendingToLoad = 0;
this.events.on('setup:bytecode-address', this._obtainContractBytecode.bind(this))
}
process(){
@ -41,21 +39,11 @@ class ContractSettings {
}
}
_determineBytecodeAddress(topicName, i){
let contractAddress = this.contracts[topicName].address;
if(this.contracts[topicName].isIdentity){
this.pendingToLoad++;
const lastKernelSignature = "0x4ac99424"; // REFACTOR
this.web3.eth.call({to: this.contracts[topicName].factoryAddress, data: lastKernelSignature})
.then(kernel => {
contractAddress = '0x' + kernel.slice(26);
this.events.emit('setup:bytecode-address', topicName, contractAddress);
})
}
}
_obtainContractBytecode(topicName){
if(this.contracts[topicName].isIdentity) return;
_obtainContractBytecode(topicName, contractAddress){
this.web3.eth.getCode(contractAddress)
this.pendingToLoad++;
this.web3.eth.getCode(this.contracts[topicName].address)
.then(code => {
this.contracts[topicName].code = md5(code);
this.pendingToLoad--;
@ -90,7 +78,7 @@ class ContractSettings {
_processContracts(){
for(let contractName in this.contracts){
// Obtaining the abis
this.contracts[contractName].abi = require(this.contracts[contractName].abiFile);
this.contracts[contractName].abi = require(this.contracts[contractName].abiFile).abi;
const topicName = this.getTopicName(contractName);
@ -100,7 +88,7 @@ class ContractSettings {
this.contracts[topicName].name = contractName;
delete this.contracts[contractName];
this._determineBytecodeAddress(topicName);
this._obtainContractBytecode(topicName);
this._extractFunctions(topicName);
}

View File

@ -1,5 +1,5 @@
const md5 = require('md5');
const erc20ABI = require('../abi/ERC20.json');
const erc20ABI = require('../abi/ERC20Token.json');
const ganache = require("ganache-cli");
class MessageProcessor {
@ -56,6 +56,15 @@ class MessageProcessor {
}
async _validateInstance(message, input){
const contract = this.settings.getContractByTopic(message.topic);
const kernelVerifSignature = this.web3.utils.sha3(contract.kernelVerification).slice(0, 10)
return await this.web3.eth.call({
to: contract.factoryAddress,
data: kernelVerifSignature + "000000000000000000000000" + input.address});
}
_extractInput(message){
return {
address: message.payload.slice(0, 42),
@ -73,6 +82,7 @@ class MessageProcessor {
}
}
_getFactor(input, contract, gasToken){
if(contract.allowedFunctions[input.functionName].isToken){
return this.web3.utils.toBN(this.settings.getToken(gasToken).pricePlugin.getFactor());
@ -87,14 +97,14 @@ class MessageProcessor {
if(token.symbol == "ETH")
return new this.web3.utils.BN(await this.web3.eth.getBalance(input.address));
else {
const Token = new this.web3.eth.Contract(erc20ABI);
const Token = new this.web3.eth.Contract(erc20ABI.abi);
Token.options.address = params('gasToken');
return new this.web3.utils.BN(await Token.methods.balanceOf(input.address).call());
}
}
_estimateGas(input){
async _estimateGas(input){
const web3Sim = new Web3(ganache.provider({fork: `${this.config.node.protocol}://${this.config.node.host}:${this.config.node.port}`}));
const simAccounts = await web3Sim.eth.getAccounts();
let simulatedReceipt = await web3Sim.eth.sendTransaction({
@ -121,6 +131,9 @@ class MessageProcessor {
if(!this._validateInput(message, input)) return; // TODO Log
if(contract.isIdentity)
if(!this._validateInstance(message, input)) return;
const params = this._obtainParametersFunc(contract, input);
const token = this.settings.getToken(params('gasToken'));

View File

@ -40,7 +40,7 @@ $(function(){
$('button').on('click', async function(e){
e.preventDefault();
$('p.result').text('');
$('p.result, #messageArea').text('');
let sKey = add0x($("#sKey"));
let msgTopic = add0x($('#topic'));

View File

@ -15,6 +15,24 @@
],
"gas": "auto",
"contracts": {
"Identity": {"deploy": false},
"IdentityFactory": {"deploy": false},
"SafeMath": {"deploy": false},
"DelayedUpdatableInstance": {"deploy": false},
"DelayedUpdatableInstanceStorage": {"deploy": false},
"Factory": {"deploy": false},
"Instance": {"deploy": false},
"InstanceStorage": {"deploy": false},
"MiniMeToken": {"deploy": false},
"MiniMeTokenFactory": {"deploy": false},
"UpdatableInstance": {"deploy": false},
"Controlled": {"deploy": false},
"Owned": {"deploy": false},
"IdentityGasRelay": {"deploy": false},
"IdentityKernel": {"deploy": false},
"SNTController": {"deploy": false},
"UpdatedIdentityKernel": {"deploy": false},
"TestContract": {"deploy": false}
}
}
}

View File

@ -50,6 +50,10 @@ contract Factory is Controlled {
);
}
function isKernel(address _addr) public returns (bool){
return versionMap[_addr] > 0;
}
function getCodeHash(address _addr)
public
view

View File

@ -6,6 +6,6 @@ import "./Identity.sol";
contract IdentityKernel is DelayedUpdatableInstanceStorage, Identity {
function initIdentity(address _caller) external {
_constructIdentity(_caller);
_constructIdentity(keccak256(_caller));
}
}