From d0b3b9113c8cff35958efaefd9986ead0bae6892 Mon Sep 17 00:00:00 2001 From: Christophe Le Bars Date: Sat, 11 Aug 2018 13:50:54 +0700 Subject: [PATCH] signature format update (v 0.12) --- contracts/RougeFactory.sol | 2 +- contracts/SimpleRougeCampaign.sol | 16 +++++++++++++--- package.json | 1 + test/CouponDemo.js | 5 +++-- test/RougeFactory.js | 6 ++++-- test/SimpleRougeCampaign.js | 19 ++++++++++--------- 6 files changed, 32 insertions(+), 17 deletions(-) diff --git a/contracts/RougeFactory.sol b/contracts/RougeFactory.sol index 0791299..1da62ba 100644 --- a/contracts/RougeFactory.sol +++ b/contracts/RougeFactory.sol @@ -14,7 +14,7 @@ import "./RougeRegistry.sol"; contract RougeFactory is RougeRegistry { - bytes8 public version = '0.11.0'; + string public version = '0.12.0'; // The Rouge Token contract address RGETokenInterface public rge; diff --git a/contracts/SimpleRougeCampaign.sol b/contracts/SimpleRougeCampaign.sol index c216b08..aa50e96 100644 --- a/contracts/SimpleRougeCampaign.sol +++ b/contracts/SimpleRougeCampaign.sol @@ -12,7 +12,7 @@ import "./RougeFactoryInterface.sol"; contract SimpleRougeCampaign { - bytes8 public version = '0.11.0'; + string public version = '0.12.0'; // The Rouge Token contract address RGETokenInterface public rge; @@ -63,8 +63,18 @@ contract SimpleRougeCampaign { } // web3.eth.sign compat prefix XXX mv to lib - function prefixed(bytes32 _message) internal pure returns (bytes32) { - return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", _message)); + function getHexString(bytes32 value) internal pure returns (string) { + bytes memory result = new bytes(64); + string memory characterString = "0123456789abcdef"; + bytes memory characters = bytes(characterString); + for (uint8 i = 0; i < 32; i++) { + result[i * 2] = characters[uint256((value[i] & 0xF0) >> 4)]; + result[i * 2 + 1] = characters[uint256(value[i] & 0xF)]; + } + return string(result); + } + function prefixed(bytes32 _hash) internal pure returns (bytes32) { + return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n74Rouge ID: ", getHexString(_hash))); } bytes4 public scheme; diff --git a/package.json b/package.json index d72e4f1..1285645 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ ], "license": "AGPL-3.0-only", "dependencies": { + "eth-sig-util": "^2.0.2", "ethereumjs-abi": "^0.6.5", "ethereumjs-util": "^5.2.0" } diff --git a/test/CouponDemo.js b/test/CouponDemo.js index b041444..717662a 100644 --- a/test/CouponDemo.js +++ b/test/CouponDemo.js @@ -69,7 +69,8 @@ contract('SimpleRougeCampaign(CouponDemo)', function(accounts) { // call acquire with auth message and attestor signature const auth1 = create_auth_hash('acceptAcquisition', campaign.address, bearer) - const sign1 = get_signature(auth1) + const sign1 = get_signature('Rouge ID: ' + auth1.substr(2)) + await campaign.acquire(auth1, sign1.v, sign1.r, sign1.s, attestor, {from: bearer}); const acquired = await campaign.acquired.call(); @@ -77,7 +78,7 @@ contract('SimpleRougeCampaign(CouponDemo)', function(accounts) { // call acceptRedemption with auth message and attestor signature const auth2 = create_auth_hash('acceptRedemption', campaign.address, bearer) - const sign2 = get_signature(auth2) + const sign2 = get_signature('Rouge ID: ' + auth2.substr(2)) await campaign.redeem(auth2, sign2.v, sign2.r, sign2.s, attestor, {from: bearer}); const redeemed = await campaign.redeemed.call(); diff --git a/test/RougeFactory.js b/test/RougeFactory.js index 79787ed..bb202d0 100644 --- a/test/RougeFactory.js +++ b/test/RougeFactory.js @@ -1,4 +1,6 @@ +const ethUtil = require('ethereumjs-util') + const RGEToken = artifacts.require("./TestRGEToken.sol"); const Factory = artifacts.require("./RougeFactory.sol"); const SimpleRougeCampaign = artifacts.require("./SimpleRougeCampaign.sol"); @@ -36,10 +38,10 @@ contract('RougeFactory', function(accounts) { const issuer_balance_post = await rge.balanceOf.call(issuer); assert.equal(issuer_balance_post.toNumber(), tokens, "issuer has receive tokens to create a campaign"); - const estimate = await rge.newCampaign.estimateGas(issuance, deposit, {from: issuer, gas: 3000000}); + const estimate = await rge.newCampaign.estimateGas(issuance, deposit, {from: issuer, gas: 3000778}); // console.log('Base estimate newCampaign => ', estimate) - const result = await rge.newCampaign(issuance, deposit, {from: issuer, gas: estimate + 60000, gasPrice: web3.toWei(1, "gwei")}) + const result = await rge.newCampaign(issuance, deposit, {from: issuer, gas: estimate + 80000, gasPrice: web3.toWei(1, "gwei")}) assert.equal(result.receipt.cumulativeGasUsed, estimate, "cumulativeGasUsed correctly predict"); diff --git a/test/SimpleRougeCampaign.js b/test/SimpleRougeCampaign.js index 2cd3897..02ecbb1 100644 --- a/test/SimpleRougeCampaign.js +++ b/test/SimpleRougeCampaign.js @@ -1,6 +1,7 @@ const abi = require('ethereumjs-abi') const BN = require('bn.js') +const ethUtil = require('ethereumjs-util') const RGEToken = artifacts.require("./TestRGEToken.sol"); const Factory = artifacts.require("./RougeFactory.sol"); @@ -34,9 +35,9 @@ const create_auth_hash = function(msg, campaign, account) { } -const get_signature = function(account, hash) { +const get_signature = function(account, msg) { - const signature = web3.eth.sign(account, hash).substr(2) + const signature = web3.eth.sign(account, ethUtil.bufferToHex(ethUtil.toBuffer(msg))).substr(2) return { r: '0x' + signature.slice(0, 64), s: '0x' + signature.slice(64, 128), @@ -96,9 +97,9 @@ contract('SimpleRougeCampaign', function(accounts) { assert.equal(acquired.toNumber(), 1, "check notes acquired after distributeNote"); // call acceptRedemption with auth message and bearer signature - const auth2 = create_auth_hash('acceptRedemption', campaign.address, bearer) - const sign2 = get_signature(bearer, auth2) - await campaign.acceptRedemption(bearer, auth2, sign2.v, sign2.r, sign2.s, {from: issuer}); + const auth = create_auth_hash('acceptRedemption', campaign.address, bearer) + const sign = get_signature(bearer, 'Rouge ID: ' + auth.substr(2)) + await campaign.acceptRedemption(bearer, auth, sign.v, sign.r, sign.s, {from: issuer}); const redeemed = await campaign.redeemed.call(); assert.equal(redeemed.toNumber(), 1, "note(s) redeemed after confirmRedemption"); @@ -131,7 +132,7 @@ contract('SimpleRougeCampaign', function(accounts) { // call acquire with auth message and issuer signature const auth1 = create_auth_hash('acceptAcquisition', campaign.address, bearer) - const sign1 = get_signature(issuer, auth1) + const sign1 = get_signature(issuer, 'Rouge ID: ' + auth1.substr(2)) await campaign.acquire(auth1, sign1.v, sign1.r, sign1.s, issuer, {from: bearer}); const acquired = await campaign.acquired.call(); @@ -139,7 +140,7 @@ contract('SimpleRougeCampaign', function(accounts) { // call acceptRedemption with auth message and issuer signature const auth2 = create_auth_hash('acceptRedemption', campaign.address, bearer) - const sign2 = get_signature(issuer, auth2) + const sign2 = get_signature(issuer, 'Rouge ID: ' + auth2.substr(2)) await campaign.redeem(auth2, sign2.v, sign2.r, sign2.s, issuer, {from: bearer}); const redeemed = await campaign.redeemed.call(); @@ -177,7 +178,7 @@ contract('SimpleRougeCampaign', function(accounts) { // call acquire with auth message and attestor signature const auth1 = create_auth_hash('acceptAcquisition', campaign.address, bearer) - const sign1 = get_signature(attestor, auth1) + const sign1 = get_signature(attestor, 'Rouge ID: ' + auth1.substr(2)) await campaign.acquire(auth1, sign1.v, sign1.r, sign1.s, attestor, {from: bearer}); const acquired = await campaign.acquired.call(); @@ -185,7 +186,7 @@ contract('SimpleRougeCampaign', function(accounts) { // call acceptRedemption with auth message and attestor signature const auth2 = create_auth_hash('acceptRedemption', campaign.address, bearer) - const sign2 = get_signature(attestor, auth2) + const sign2 = get_signature(attestor, 'Rouge ID: ' + auth2.substr(2)) await campaign.redeem(auth2, sign2.v, sign2.r, sign2.s, attestor, {from: bearer}); const redeemed = await campaign.redeemed.call();