Sending transaction logic for js lib.

This commit is contained in:
Richard Ramos 2018-09-01 07:23:24 -04:00
parent 69e8167499
commit 1f14d25dec
2 changed files with 131 additions and 60 deletions

View File

@ -1,4 +1,5 @@
import React, {Component} from 'react';
import StatusGasRelayer, {Contracts} 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';
@ -6,7 +7,6 @@ import CardContent from '@material-ui/core/CardContent';
import CardHeader from '@material-ui/core/CardHeader';
import EmbarkJS from 'Embark/EmbarkJS';
import Grid from '@material-ui/core/Grid';
import IdentityGasRelay from 'Embark/contracts/IdentityGasRelay';
import MySnackbarContentWrapper from './snackbar';
import PropTypes from 'prop-types';
import STT from 'Embark/contracts/STT';
@ -16,9 +16,6 @@ import config from '../config';
import web3 from 'Embark/web3';
import {withStyles} from '@material-ui/core/styles';
import StatusGasRelayer, {Contracts} from '../status-gas-relayer';
const styles = theme => ({
root: {
width: '100%',
@ -83,7 +80,7 @@ class CallGasRelayed extends Component {
const s = new StatusGasRelayer.Identity(this.props.identityAddress, web3.eth.defaultAccount)
.setTransaction(this.state.to, this.state.value, this.state.data)
.setGas(this.state.gasToken, this.state.gasPrice, this.state.gasLimit);
const signature = await s.sign(web3);
this.setState({signature});
@ -118,7 +115,7 @@ class CallGasRelayed extends Component {
}
}
sendTransaction = event => {
sendTransaction = async event => {
event.preventDefault();
const {web3, kid} = this.props;
@ -135,38 +132,16 @@ class CallGasRelayed extends Component {
this.props.clearMessages();
try {
let jsonAbi = IdentityGasRelay._jsonInterface.filter(x => x.name == "callGasRelayed")[0];
let funCall = web3.eth.abi.encodeFunctionCall(jsonAbi, [
this.state.to,
this.state.value,
this.state.data,
this.props.nonce,
this.state.gasPrice,
this.state.gasLimit,
this.state.gasToken,
this.state.signature
]);
const sendOptions = {
ttl: 1000,
sig: kid,
powTarget: 1,
powTime: 20,
topic: this.state.topic,
pubKey: relayer,
payload: web3.utils.toHex({
'contract': this.props.identityAddress,
'address': web3.eth.defaultAccount,
'action': 'transaction',
'encodedFunctionCall': funCall
})
};
web3.shh.post(sendOptions)
.then(() => {
this.setState({submitting: false});
console.log("Message sent");
return true;
});
const s = new StatusGasRelayer.Identity(this.props.identityAddress, web3.eth.defaultAccount)
.setTransaction(this.state.to, this.state.value, this.state.data)
.setGas(this.state.gasToken, this.state.gasPrice, this.state.gasLimit)
.setRelayer(relayer)
.setAsymmetricKeyID(kid);
await s.post(this.state.signature, web3);
this.setState({submitting: false});
console.log("Message sent");
} catch(error){
this.setState({messagingError: error.message, submitting: false});
}

View File

@ -19,21 +19,34 @@ const relayerSymmmetricKeyID = "0xd0d905c1c62b810b787141430417caf2b3f54cffadb395
class StatusGasRelayer {
constructor(build, web3) {
if (arguments.length !== 2 || !this.validateBuild(build)) throw new Error("Invalid build");
this.web3 = web3;
if (arguments.length === 2 && this.validateBuild(build)) {
Object.defineProperties(this, {
message: {
value: build._getMessage(web3),
writable: false
},
topic: {
value: web3.utils.toHex(build.contractName).slice(0, 10),
writable: false
},
kid: {
value: build.kid,
writable: false
}
});
if(build.operation === Actions.Transaction){
Object.defineProperties(this, {
message: {
value: build._getMessage(web3),
pubKey: {
value: build.relayer,
writable: false
},
topic: {
value: web3.utils.toHex(build.contractName).slice(0, 10),
writable: false
},
kid: {
value: build.kid,
writable: false
},
}
});
} else {
Object.defineProperties(this, {
skid: {
value: build.skid,
writable: false
@ -45,10 +58,8 @@ class StatusGasRelayer {
post = async (options) => {
options = options || {};
let pubKey = options.pubKey || this.pubKey;
let skid = options.skid || this.skid;
if(!skid){
skid = await this.web3.shh.addSymKey(relayerSymmmetricKeyID);
}
let kid = options.kid || this.kid;
if(!kid){
@ -61,10 +72,18 @@ class StatusGasRelayer {
powTarget: options.powTarget || 1,
powTime: options.powTime || 20,
topic: this.topic,
symKeyID: skid,
payload: this.web3.utils.toHex(this.message)
};
if(pubKey){
sendOptions.pubKey = pubKey;
} else {
if(!skid){
skid = await this.web3.shh.addSymKey(relayerSymmmetricKeyID);
}
sendOptions.symKeyID = skid;
}
const msgId = await this.web3.shh.post(sendOptions);
return msgId;
}
@ -97,6 +116,11 @@ class Action {
return this;
}
setRelayer(relayer){
this.relayer = relayer;
return this;
}
setRelayersSymKeyID = (skid) => {
this.skid = skid;
return this;
@ -138,7 +162,7 @@ class IdentityGasRelayedAction extends Action {
return nonce;
}
sign = async (web3) => {
sign = async web3 => {
const contract = new web3.eth.Contract(identityGasRelayABI, this.contractAddress);
const nonce = await this._nonce(contract);
@ -153,14 +177,38 @@ class IdentityGasRelayedAction extends Action {
this.gasToken
).call();
const signature = await web3.eth.sign(hashedMessage, this.accountAddress);
const signedMessage = await web3.eth.sign(hashedMessage, this.accountAddress);
return signature;
return signedMessage;
}
_getMessage = async web3 => {
return {
post = async (signature, web3, options) => {
this.nonce = await this.getNonce(web3);
this.signature = signature;
const s = new StatusGasRelayer(this, web3);
return s.post(options);
}
_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
]);
return {
'contract': this.contractAddress,
'address': this.accountAddress,
'action': Actions.Transaction,
'encodedFunctionCall': funCall
};
}
}
@ -253,7 +301,55 @@ const identityGasRelayABI = [
"stateMutability": "view",
"type": "function",
"signature": "0xaffed0e0"
}
},
{
"constant": false,
"inputs": [
{
"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": "callGasRelayed",
"outputs": [
{
"name": "success",
"type": "bool"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "function",
"signature": "0xfd0dded5"
}
];
export default StatusGasRelayer;