add sendwithapproval method

use send with approval
This commit is contained in:
Barry Gitarts 2018-08-14 16:03:15 -04:00
parent 4b45590496
commit 1ea3b8b149
4 changed files with 116 additions and 98 deletions

View File

@ -12,10 +12,10 @@ import { getStatusContactCode, getSNTAllowance } from '../../reducers/accounts';
import FieldGroup from '../standard/FieldGroup';
import LinearProgress from '@material-ui/core/LinearProgress';
import { generateXY } from '../../utils/ecdsa';
console.log(TestToken)
import { BigNumber } from '../standard/utils';
const { soliditySha3, fromWei } = web3.utils;
const unlimitedAllowance = new BigNumber(2).pow(256).sub(1);
const InnerForm = ({
values,
@ -33,98 +33,98 @@ const InnerForm = ({
}) => (
<form onSubmit={handleSubmit}>
<div style={{ margin: '10px' }}>
{!subDomain &&
<FieldGroup
id="subDomain"
name="subDomain"
type="text"
label="Sub Domain"
onChange={handleChange}
onBlur={handleBlur}
value={values.subDomain}
error={errors.subDomain}
/>}
{!domainName &&
<FieldGroup
id="domainName"
name="domainName"
type="text"
label="Domain Name"
onChange={handleChange}
onBlur={handleBlur}
value={values.domainName}
button={
<Button
mode="strong"
style={{ marginTop: '5px' }}
{!subDomain &&
<FieldGroup
id="subDomain"
name="subDomain"
type="text"
label="Sub Domain"
onChange={handleChange}
onBlur={handleBlur}
value={values.subDomain}
error={errors.subDomain}
/>}
{!domainName &&
<FieldGroup
id="domainName"
name="domainName"
type="text"
label="Domain Name"
onChange={handleChange}
onBlur={handleBlur}
value={values.domainName}
button={
<Button
mode="strong"
style={{ marginTop: '5px' }}
onClick={() => {
ENSSubdomainRegistry.methods.getPrice(hash(values.domainName))
.call()
.then((res) => { setFieldValue('price', fromWei(res)); });
}}
>
Get Price
</Button>
}
/>}
{!domainPrice &&
<FieldGroup
id="price"
name="price"
label="Domain Price"
disabled
value={values.price ? `${formatPrice(values.price)} SNT` : ''} />}
<Hidden mdDown>
<FieldGroup
id="statusAddress"
name="statusAddress"
type="text"
label="Status messenger address domain resolves to"
onChange={handleChange}
onBlur={handleBlur}
value={values.statusAddress}
error={errors.statusAddress}
wide="true"
/>
<FieldGroup
id="address"
name="address"
type="text"
label="Ethereum address domain resolves to"
onChange={handleChange}
onBlur={handleBlur}
value={values.address}
error={errors.address}
button={<Button mode="strong" style={{ padding: '5px 15px 5px 15px', marginTop: '5px' }} onClick={() => setFieldValue('address', web3.eth.defaultAccount)}>Use My Primary Address</Button>}
/>
{!isSubmitting ? <Button wide mode="strong" type="submit" disabled={isSubmitting || !!Object.keys(errors).length}>{!isSubmitting ? 'Submit' : 'Submitting to the Blockchain - (this may take awhile)'}</Button> : <LinearProgress />}
</Hidden>
<Hidden mdUp>
<Field label="Your Contact Code">
<MobileSearch
>
Get Price
</Button>
}
/>}
{!domainPrice &&
<FieldGroup
id="price"
name="price"
label="Domain Price"
disabled
value={values.price ? `${formatPrice(values.price)} SNT` : ''} />}
<Hidden mdDown>
<FieldGroup
id="statusAddress"
name="statusAddress"
style={{ marginTop: '10px' }}
placeholder="Status Messenger Address"
type="text"
label="Status messenger address domain resolves to"
onChange={handleChange}
onBlur={handleBlur}
value={values.statusAddress}
onChange={handleChange}
paste={() => setFieldValue('statusAddress', statusContactCode)}
wide />
</Field>
<Field label="Your Wallet Address">
<MobileSearch
error={errors.statusAddress}
wide="true"
/>
<FieldGroup
id="address"
name="address"
style={{ marginTop: '10px' }}
placeholder="Ethereum Address"
value={values.address}
type="text"
label="Ethereum address domain resolves to"
onChange={handleChange}
paste={() => setFieldValue('address', web3.eth.defaultAccount)}
required
wide />
</Field>
<div style={{ position: 'relative', left: 0, right: 0, bottom: 0 }}>
<MobileButton type="submit" text="Register with transaction" style={{ width: '100%' }}/>
</div>
</Hidden>
onBlur={handleBlur}
value={values.address}
error={errors.address}
button={<Button mode="strong" style={{ padding: '5px 15px 5px 15px', marginTop: '5px' }} onClick={() => setFieldValue('address', web3.eth.defaultAccount)}>Use My Primary Address</Button>}
/>
{!isSubmitting ? <Button wide mode="strong" type="submit" disabled={isSubmitting || !!Object.keys(errors).length}>{!isSubmitting ? 'Submit' : 'Submitting to the Blockchain - (this may take awhile)'}</Button> : <LinearProgress />}
</Hidden>
<Hidden mdUp>
<Field label="Your Contact Code">
<MobileSearch
name="statusAddress"
style={{ marginTop: '10px' }}
placeholder="Status Messenger Address"
value={values.statusAddress}
onChange={handleChange}
paste={() => setFieldValue('statusAddress', statusContactCode)}
wide />
</Field>
<Field label="Your Wallet Address">
<MobileSearch
name="address"
style={{ marginTop: '10px' }}
placeholder="Ethereum Address"
value={values.address}
onChange={handleChange}
paste={() => setFieldValue('address', web3.eth.defaultAccount)}
required
wide />
</Field>
<div style={{ position: 'relative', left: 0, right: 0, bottom: 0 }}>
<MobileButton type="submit" text="Register with transaction" style={{ width: '100%' }}/>
</div>
</Hidden>
</div>
</form>
);
@ -142,22 +142,34 @@ const RegisterSubDomain = withFormik({
handleSubmit(values, { setSubmitting, props }) {
const { address, statusAddress } = values;
const { subDomain, domainName, registeredCallbackFn } = props || values;
const { SNTAllowance } = props;
const { methods: { register } } = ENSSubdomainRegistry;
const subdomainHash = soliditySha3(subDomain);
const domainNameHash = hash(domainName);
const resolveToAddr = address || zeroAddress;
const points = statusAddress ? generateXY(statusAddress) : null;
const toSend = register(
const registerAbi = ENSSubdomainRegistry.options.jsonInterface.find(x => x.name === 'register');
const encodedRegister = web3.eth.abi.encodeFunctionCall(registerAbi, [
subdomainHash,
domainNameHash,
resolveToAddr,
points ? points.x : zeroBytes32,
points ? points.y : zeroBytes32
]);
const sendWithApproval = TestToken.methods.approveAndCall(ENSSubdomainRegistry._address, unlimitedAllowance, encodedRegister);
const send = register(
subdomainHash,
domainNameHash,
resolveToAddr,
points ? points.x : zeroBytes32,
points ? points.y : zeroBytes32
);
toSend.estimateGas().then(gasEstimated => {
console.log("Register would work. :D Gas estimated: "+gasEstimated)
console.log("Trying: register(\""+subdomainHash+"\",\""+domainNameHash+"\",\""+resolveToAddr+"\",\""+zeroBytes32+"\",\""+zeroBytes32+"\")")
const toSend = Number(SNTAllowance) > 0 ? send : sendWithApproval;
toSend.estimateGas({ data: encodedRegister }).then(gasEstimated => {
console.log("Register would work. :D Gas estimated: " + gasEstimated);
console.log("Trying: register(\"" + subdomainHash + "\",\"" + domainNameHash+"\",\""+resolveToAddr+"\",\""+zeroBytes32+"\",\""+zeroBytes32+"\")")
toSend.send({gas: gasEstimated+1000}).then(txId => {
if(txId.status == "0x1" || txId.status == "0x01"){
console.log("Register send success. :)")

View File

@ -1,5 +0,0 @@
pragma solidity ^0.4.11;
contract ApprovalReceiver {
function receiveApproval(address from, uint value, address tokenContract, bytes extraData) returns (bool);
}

View File

@ -0,0 +1,5 @@
pragma solidity ^0.4.11;
contract ApproveAndCallFallBack {
function receiveApproval(address from, uint256 _amount, address _token, bytes _data) returns (bool);
}

View File

@ -1,7 +1,7 @@
pragma solidity ^0.4.23;
import "./StandardToken.sol";
import './ApprovalReceiver.sol';
import './ApproveAndCallFallBack.sol';
/**
* @notice ERC20Token for test scripts, can be minted by anyone.
@ -18,9 +18,15 @@ contract TestToken is StandardToken {
mint(msg.sender, _amount);
}
function approveAndCall(address _spender, uint256 _value, bytes _extraData) returns (bool success) {
assert(approve(_spender, _value));
return ApprovalReceiver(_spender).receiveApproval(msg.sender, _value, this, _extraData);
function approveAndCall(address _spender, uint256 _amount, bytes _extraData) returns (bool success) {
if (!approve(_spender, _amount)) throw;
ApproveAndCallFallBack(_spender).receiveApproval(
msg.sender,
_amount,
this,
_extraData
);
return true;
}
}