From f3557762cda864168c1a9fec27257d46742c6623 Mon Sep 17 00:00:00 2001 From: Richard Ramos Date: Sat, 1 Sep 2018 07:42:44 -0400 Subject: [PATCH] Added approveAndCallGasRelayed function --- test-dapp/app/components/callgasrelayed.js | 4 +- test-dapp/app/status-gas-relayer.js | 184 ++++++++++++++++++--- 2 files changed, 164 insertions(+), 24 deletions(-) diff --git a/test-dapp/app/components/callgasrelayed.js b/test-dapp/app/components/callgasrelayed.js index fef747e..70c6475 100644 --- a/test-dapp/app/components/callgasrelayed.js +++ b/test-dapp/app/components/callgasrelayed.js @@ -1,5 +1,5 @@ import React, {Component} from 'react'; -import StatusGasRelayer, {Contracts} from '../status-gas-relayer'; +import StatusGasRelayer, {Contracts, Functions} from '../status-gas-relayer'; import Button from '@material-ui/core/Button'; import Card from '@material-ui/core/Card'; import CardActions from '@material-ui/core/CardActions'; @@ -78,6 +78,7 @@ class CallGasRelayed extends Component { try { const s = new StatusGasRelayer.Identity(this.props.identityAddress, web3.eth.defaultAccount) + .setContractFunction(Functions.Identity.call) .setTransaction(this.state.to, this.state.value, this.state.data) .setGas(this.state.gasToken, this.state.gasPrice, this.state.gasLimit); @@ -133,6 +134,7 @@ class CallGasRelayed extends Component { try { const s = new StatusGasRelayer.Identity(this.props.identityAddress, web3.eth.defaultAccount) + .setContractFunction(Functions.Identity.call) .setTransaction(this.state.to, this.state.value, this.state.data) .setGas(this.state.gasToken, this.state.gasPrice, this.state.gasLimit) .setRelayer(relayer) diff --git a/test-dapp/app/status-gas-relayer.js b/test-dapp/app/status-gas-relayer.js index f1049e1..6fc9578 100644 --- a/test-dapp/app/status-gas-relayer.js +++ b/test-dapp/app/status-gas-relayer.js @@ -143,6 +143,11 @@ class IdentityGasRelayedAction extends Action { return this; } + setContractFunction = contractFunction => { + this.contractFunction = contractFunction; + return this; + } + setTransaction = (to, value, data) => { this.to = to; this.value = value; @@ -151,6 +156,11 @@ class IdentityGasRelayedAction extends Action { return this; } + setBaseToken = baseToken => { + this.baseToken = baseToken; + return this; + } + _nonce = async(contract) => { const nonce = await contract.methods.nonce().call(); return nonce; @@ -165,18 +175,34 @@ class IdentityGasRelayedAction extends Action { sign = async web3 => { const contract = new web3.eth.Contract(identityGasRelayABI, this.contractAddress); const nonce = await this._nonce(contract); + let hashedMessage; - // TODO: this depends of the operation to execute - const hashedMessage = await contract.methods.callGasRelayHash( - this.to, - this.value, - web3.utils.soliditySha3({t: 'bytes', v: this.data}), - nonce, - this.gasPrice, - this.gasLimit, - this.gasToken - ).call(); - + switch(this.contractFunction){ + case Functions.Identity.call: + hashedMessage = await contract.methods.callGasRelayHash( + this.to, + this.value, + web3.utils.soliditySha3({t: 'bytes', v: this.data}), + nonce, + this.gasPrice, + this.gasLimit, + this.gasToken + ).call(); + break; + case Functions.Identity.approveAndCall: + hashedMessage = await contract.methods.deployGasRelayHash( + this.value, + web3.utils.soliditySha3({t: 'bytes', v: this.data}), + nonce, + this.gasPrice, + this.gasLimit, + this.gasToken + ).call(); + break; + default: + throw new Error("Function not allowed"); + } + const signedMessage = await web3.eth.sign(hashedMessage, this.accountAddress); return signedMessage; @@ -191,18 +217,38 @@ class IdentityGasRelayedAction extends Action { } _getMessage = web3 => { - // TODO: this depends on the operation to execute - let jsonAbi = identityGasRelayABI.find(x => x.name == "callGasRelayed"); - let funCall = web3.eth.abi.encodeFunctionCall(jsonAbi, [ - this.to, - this.value, - this.data, - this.nonce, - this.gasPrice, - this.gasLimit, - this.gasToken, - this.signature - ]); + let jsonAbi = identityGasRelayABI.find(x => x.name == this.contractFunction); + let funCall; + + switch(this.contractFunction){ + case Functions.Identity.call: + funCall = web3.eth.abi.encodeFunctionCall(jsonAbi, [ + this.to, + this.value, + this.data, + this.nonce, + this.gasPrice, + this.gasLimit, + this.gasToken, + this.signature + ]); + break; + case Functions.Identity.approveAndCall: + funCall = web3.eth.abi.encodeFunctionCall(jsonAbi, [ + this.baseToken, + this.to, + this.value, + this.data, + this.nonce, + this.gasPrice, + this.gasLimit, + this.gasToken, + this.signature + ]); + break; + default: + throw new Error("Function not allowed"); + } return { 'contract': this.contractAddress, @@ -349,6 +395,98 @@ const identityGasRelayABI = [ "stateMutability": "nonpayable", "type": "function", "signature": "0xfd0dded5" + }, + { + "constant": false, + "inputs": [ + { + "name": "_baseToken", + "type": "address" + }, + { + "name": "_to", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + }, + { + "name": "_data", + "type": "bytes" + }, + { + "name": "_nonce", + "type": "uint256" + }, + { + "name": "_gasPrice", + "type": "uint256" + }, + { + "name": "_gasLimit", + "type": "uint256" + }, + { + "name": "_gasToken", + "type": "address" + }, + { + "name": "_messageSignatures", + "type": "bytes" + } + ], + "name": "approveAndCallGasRelayed", + "outputs": [ + { + "name": "success", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function", + "signature": "0x59f4ac61" + }, + { + "constant": true, + "inputs": [ + { + "name": "_value", + "type": "uint256" + }, + { + "name": "_dataHash", + "type": "bytes32" + }, + { + "name": "_nonce", + "type": "uint256" + }, + { + "name": "_gasPrice", + "type": "uint256" + }, + { + "name": "_gasLimit", + "type": "uint256" + }, + { + "name": "_gasToken", + "type": "address" + } + ], + "name": "deployGasRelayHash", + "outputs": [ + { + "name": "_callGasRelayHash", + "type": "bytes32" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function", + "signature": "0x86962d85" } ];