storing ipfs hash in bytes32 hash and changed receiveApproval (#23)

This commit is contained in:
Andy Tudhope 2019-04-12 11:40:24 +02:00 committed by GitHub
parent 849787cb71
commit 800ad2270e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 57 additions and 17 deletions

View File

@ -31,7 +31,7 @@ contract DAppStore is ApproveAndCallFallBack, BancorFormula {
struct Data {
address developer;
bytes32 id;
bytes metadata;
bytes32 metadata;
uint balance;
uint rate;
uint available;
@ -68,9 +68,14 @@ contract DAppStore is ApproveAndCallFallBack, BancorFormula {
* @dev Anyone can create a DApp (i.e an arb piece of data this contract happens to care about).
* @param _id bytes32 unique identifier.
* @param _amount of tokens to stake on initial ranking.
* @param _metadata metadata hex string
*/
function createDApp(bytes32 _id, uint _amount) external {
_createDApp(msg.sender, _id, _amount);
function createDApp(bytes32 _id, uint _amount, bytes32 _metadata) external {
_createDApp(
msg.sender,
_id,
_amount,
_metadata);
}
/**
@ -139,9 +144,9 @@ contract DAppStore is ApproveAndCallFallBack, BancorFormula {
/**
* dev Set the content for the dapp
* @param _id bytes32 unique identifier.
* @param _metadata IPFS hash of the metadata
* @param _metadata metadata info
*/
function setMetadata(bytes32 _id, bytes calldata _metadata) external {
function setMetadata(bytes32 _id, bytes32 _metadata) external {
uint dappIdx = id2index[_id];
Data storage d = dapps[dappIdx];
require(d.developer == msg.sender, "Only the developer can update the metadata");
@ -166,18 +171,22 @@ contract DAppStore is ApproveAndCallFallBack, BancorFormula {
{
require(_token == address(SNT), "Wrong token");
require(_token == address(msg.sender), "Wrong account");
require(_data.length <= 132, "Incorrect data");
require(_data.length <= 196, "Incorrect data");
bytes4 sig;
bytes32 id;
uint256 amount;
bytes32 metadata;
(sig, id, amount) = abiDecodeRegister(_data);
(sig, id, amount, metadata) = abiDecodeRegister(_data);
require(_amount == amount, "Wrong amount");
if (sig == bytes4(0x1a214f43)) {
_createDApp(_from, id, amount);
if (sig == bytes4(0x7e38d973)) {
_createDApp(
_from,
id,
amount,
metadata);
} else if (sig == bytes4(0xac769090)) {
_downvote(_from, id, amount);
} else if (sig == bytes4(0x2b3df690)) {
@ -246,7 +255,14 @@ contract DAppStore is ApproveAndCallFallBack, BancorFormula {
return (balanceDownBy, votesRequired, cost);
}
function _createDApp(address _from, bytes32 _id, uint _amount) internal {
function _createDApp(
address _from,
bytes32 _id,
uint _amount,
bytes32 _metadata
)
internal
{
require(!existingIDs[_id], "You must submit a unique ID");
require(_amount > 0, "You must spend some SNT to submit a ranking in order to avoid spam");
@ -259,6 +275,7 @@ contract DAppStore is ApproveAndCallFallBack, BancorFormula {
Data storage d = dapps[dappIdx];
d.developer = _from;
d.id = _id;
d.metadata = _metadata;
uint precision;
uint result;
@ -351,16 +368,19 @@ contract DAppStore is ApproveAndCallFallBack, BancorFormula {
bytes memory _data
)
private
pure
returns(
bytes4 sig,
bytes32 id,
uint256 amount
uint256 amount,
bytes32 metadata
)
{
assembly {
sig := mload(add(_data, add(0x20, 0)))
id := mload(add(_data, 36))
amount := mload(add(_data, 68))
metadata := mload(add(_data, 100))
}
}

View File

@ -5,6 +5,8 @@
"private": true,
"dependencies": {
"@trailofbits/embark-contract-info": "^1.0.0",
"bignumber.js": "^8.1.1",
"bs58": "^4.0.1",
"connected-react-router": "^6.3.2",
"debounce": "^1.2.0",
"decimal.js": "^10.0.2",

View File

@ -54,9 +54,10 @@ contract("DAppStore", function () {
it("should create a new DApp and initialise it correctly", async function () {
let id = "0x7465737400000000000000000000000000000000000000000000000000000000";
let amount = 10000;
let metadata = "QmSmv5e5DYc2otwWcpUzuqmt389s3HHx651TbxDvKBFFue";
await SNT.methods.generateTokens(accounts[0], amount).send();
const encodedCall = DAppStore.methods.createDApp(id,amount).encodeABI();
const encodedCall = DAppStore.methods.createDApp(id,amount,TestUtils.getBytes32FromIpfsHash(metadata)).encodeABI();
await SNT.methods.approveAndCall(DAppStore.options.address, amount, encodedCall).send({from: accounts[0]});
let receipt = await DAppStore.methods.dapps(0).call();
@ -64,6 +65,7 @@ contract("DAppStore", function () {
assert.strictEqual(developer, receipt.developer);
assert.strictEqual(id, receipt.id);
assert.strictEqual(metadata, TestUtils.getIpfsHashFromBytes32(receipt.metadata));
// Check the DApp Store actually receives the SNT!
let bal_receipt = await SNT.methods.balanceOf(DAppStore.options.address).call();
@ -90,9 +92,10 @@ contract("DAppStore", function () {
it("should not create a new DApp with the same ID", async function () {
let id = "0x7465737400000000000000000000000000000000000000000000000000000000";
let amount = 1000;
let metadata = 'QmSmv5e5DYc2otwWcpUzuqmt389s3HHx651TbxDvKBFFue';
await SNT.methods.generateTokens(accounts[0], amount).send();
const encodedCall = DAppStore.methods.createDApp(id,amount).encodeABI();
const encodedCall = DAppStore.methods.createDApp(id,amount, TestUtils.getBytes32FromIpfsHash(metadata)).encodeABI();
try {
await SNT.methods.approveAndCall(DAppStore.options.address, amount, encodedCall).send({from: accounts[0]});
@ -104,13 +107,14 @@ contract("DAppStore", function () {
it("should not create a new DApp when exceeding the ceiling or staking nothing", async function () {
let id = "0x7465737400000000000000000000000000000000000000000000000000000000";
let metadata = 'QmSmv5e5DYc2otwWcpUzuqmt389s3HHx651TbxDvKBFFue';
let initial = await DAppStore.methods.max().call();
let amount = parseInt(initial, 10);
let amount0 = 0;
await SNT.methods.generateTokens(accounts[0], amount).send();
const encodedCall = DAppStore.methods.createDApp(id,amount).encodeABI();
const encodedCall = DAppStore.methods.createDApp(id,amount,TestUtils.getBytes32FromIpfsHash(metadata)).encodeABI();
try {
await SNT.methods.approveAndCall(DAppStore.options.address, amount, encodedCall).send({from: accounts[0]});
assert.fail('should have reverted before');
@ -118,7 +122,7 @@ contract("DAppStore", function () {
TestUtils.assertJump(error);
}
const encodedCall0 = DAppStore.methods.createDApp(id,amount0).encodeABI();
const encodedCall0 = DAppStore.methods.createDApp(id,amount0,TestUtils.getBytes32FromIpfsHash(metadata)).encodeABI();
try {
await SNT.methods.approveAndCall(DAppStore.options.address, amount0, encodedCall0).send({from: accounts[0]});
assert.fail('should have reverted before');

View File

@ -1,4 +1,5 @@
/*global assert, web3*/
const bs58 = require('bs58');
// This has been tested with the real Ethereum network and Testrpc.
// Copied and edited from: https://gist.github.com/xavierlepretre/d5583222fde52ddfbc58b7cfa0d2d0a9
@ -146,3 +147,16 @@ exports.assertReverts = (contractMethodCall, maxGasAvailable) => {
await evmMethod("evm_increaseTime", [Number(amount)]);
await evmMethod("evm_mine");
};
exports.getBytes32FromIpfsHash = ipfsListing => {
const decodedHash = bs58.decode(ipfsListing).slice(2).toString('hex')
return `0x${decodedHash}`
}
exports.getIpfsHashFromBytes32 = bytes32Hex => {
const hashHex = `1220${bytes32Hex.slice(2)}`
const hashBytes = Buffer.from(hashHex, 'hex')
const hashStr = bs58.encode(hashBytes)
return hashStr
}