Skip to content
This repository has been archived by the owner on Jan 12, 2019. It is now read-only.

Commit

Permalink
Merge pull request #14 from MoMannn/dev
Browse files Browse the repository at this point in the history
ChainableXcert
  • Loading branch information
xpepermint committed Apr 7, 2018
2 parents d0e42f0 + 6ddae20 commit 084a1f8
Show file tree
Hide file tree
Showing 8 changed files with 177 additions and 12 deletions.
4 changes: 3 additions & 1 deletion test/mocks/XcertMock.sol → contracts/mocks/XcertMock.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ pragma solidity ^0.4.19;

import "../../contracts/tokens/BurnableXcert.sol";
import "../../contracts/tokens/SettableTransferXcert.sol";
import "../../contracts/tokens/ChainableXcert.sol";

contract XcertMock is BurnableXcert, SettableTransferXcert {
contract XcertMock is BurnableXcert, SettableTransferXcert, ChainableXcert {

function XcertMock(string _name, string _symbol)
BurnableXcert(_name, _symbol)
SettableTransferXcert(_name, _symbol)
ChainableXcert(_name, _symbol)
public
{

Expand Down
68 changes: 68 additions & 0 deletions contracts/tokens/ChainableXcert.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
pragma solidity ^0.4.19;

import "./Xcert.sol";

contract ChainableXcert is Xcert {

/*
* @dev This emits when additional proof is chained.
*/
event ChainedProof(uint256 indexed tokenId, string proof, uint256 index);

function ChainableXcert(string _name,
string _symbol)
Xcert(_name, _symbol)
public
{
supportedInterfaces[0xc1dcb551] = true; // ChainableXcert
}

/*
* @dev Adds new proof to chain of proofs for token.
* @param _tokenId Id of Xcert that we want to add proof to.
* @param _proof New proof we want to add to NFToken.
*/
function chain(uint256 _tokenId,
string _proof)
validNFToken(_tokenId)
onlyOwner
external
{

require(bytes(_proof).length > 0);

idToProof[_tokenId].push(_proof);

ChainedProof(_tokenId, _proof, idToProof[_tokenId].length.sub(1));
}

/*
* @dev Gets proof by index.
* @param _tokenId Id of the Xcert we want to get proof of.
* @param _index Index of the proof we want to get.
*/
function getProofByIndex(uint256 _tokenId,
uint256 _index)
validNFToken(_tokenId)
external
view
returns (string)
{
require(_index < idToProof[_tokenId].length);
return idToProof[_tokenId][_index];
}

/*
* @dev Gets the count of all proofs for a Xcert.
* @param _tokenId Id of the Xcert we want to get proof of.
*/
function getProofCount(uint256 _tokenId)
validNFToken(_tokenId)
external
view
returns (uint256)
{
return idToProof[_tokenId].length;
}

}
12 changes: 3 additions & 9 deletions contracts/tokens/Xcert.sol
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ contract Xcert is Ownable, ERC721, ERC721Metadata, ERC165 {
/*
* @dev Mapping from NFToken ID to proof.
*/
mapping (uint256 => string) internal idToProof;
mapping (uint256 => string[]) internal idToProof;

/*
* @dev Mapping of supported intefraces.
Expand Down Expand Up @@ -103,11 +103,6 @@ contract Xcert is Ownable, ERC721, ERC721Metadata, ERC165 {
*/
event MintAuthorizedAddress(address indexed _target, bool _authorized);

/*
* @dev this emits everytime a new Xcert contract is deployed.
*/
event XcertContractDeployed(address _contractAddress, string _name, string _symbol);

/*
* @dev Guarantees that the msg.sender is an owner or operator of the given NFToken.
* @param _tokenId ID of the NFToken to validate.
Expand Down Expand Up @@ -164,7 +159,6 @@ contract Xcert is Ownable, ERC721, ERC721Metadata, ERC165 {
supportedInterfaces[0x80ac58cd] = true; // ERC721
supportedInterfaces[0x5b5e139f] = true; // ERC721Metadata
supportedInterfaces[0x58c66b9f] = true; // Xcert
XcertContractDeployed(address(this), _name, _symbol);
}

/*
Expand Down Expand Up @@ -391,7 +385,7 @@ contract Xcert is Ownable, ERC721, ERC721Metadata, ERC165 {
require(bytes(_proof).length > 0);

idToUri[_id] = _uri;
idToProof[_id] = _proof;
idToProof[_id].push(_proof);
addNFToken(_to, _id);

Transfer(address(0), _to, _id);
Expand All @@ -408,7 +402,7 @@ contract Xcert is Ownable, ERC721, ERC721Metadata, ERC165 {
view
returns (string)
{
return idToProof[_tokenId];
return idToProof[_tokenId][idToProof[_tokenId].length.sub(1)];
}

/*
Expand Down
8 changes: 8 additions & 0 deletions contracts/utils/Selector.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ pragma solidity ^0.4.19;
import "../tokens/Xcert.sol";
import "../tokens/BurnableXcert.sol";
import "../tokens/SettableTransferXcert.sol";
import "../tokens/ChainableXcert.sol";

contract Selector {

Expand All @@ -23,4 +24,11 @@ contract Selector {
SettableTransferXcert i;
return i.setTransferable.selector;
}

function calculateChainableXcertSelector() public pure returns (bytes4) {
ChainableXcert i;
return i.chain.selector
^ i.getProofByIndex.selector
^ i.getProofCount.selector;
}
}
44 changes: 44 additions & 0 deletions test/tokens/ChainableXcert.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
const ChainableXcert = artifacts.require('ChainableXcert');
const util = require('ethjs-util');
const assertRevert = require('../helpers/assertRevert');

contract('ChainableXcert', (accounts) => {
let xcert;
let id1 = web3.sha3('test1');
let mockProof = "1e205550c271490347e5e2393a02e94d284bbe9903f023ba098355b8d75974c8";
let mockProof2 = "1e205550c271490347e5e2393a02e94d284bbe9903f023ba098355b8d75974d5";

beforeEach(async function () {
xcert = await ChainableXcert.new('Foo', 'F');
await xcert.mint(accounts[0], id1, mockProof, 'url1');
});

it('correctly chains additional proof', async () => {
await xcert.chain(id1, mockProof2);
var proof = await xcert.getProof(id1);
assert.equal(proof, mockProof2);
});

it('reverts trying to chain empty proof', async () => {
await assertRevert(xcert.chain(id1, ""));
});

it('correctly gets proof by index', async () => {
await xcert.chain(id1, mockProof2);
var proof = await xcert.getProofByIndex(id1, 1);
assert.equal(proof, mockProof2);
});

it('reverts trying to get proof for none existant index', async () => {
await assertRevert(xcert.getProofByIndex(id1, 1));
});

it('returns correct proof count', async () => {
var proofCount = await xcert.getProofCount(id1);
assert.equal(proofCount, 1);

await xcert.chain(id1, mockProof2);
proofCount = await xcert.getProofCount(id1);
assert.equal(proofCount, 2);
});
});
10 changes: 8 additions & 2 deletions test/tokens/XcertMock.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,28 @@ contract('XcertMock', (accounts) => {
let id3 = web3.sha3('test3');
let id4 = web3.sha3('test4');
let mockProof = "1e205550c271490347e5e2393a02e94d284bbe9903f023ba098355b8d75974c8";
let mockProof2 = "1e205550c271490347e5e2393a02e94d284bbe9903f023ba098355b8d75974d7";

beforeEach(async function () {
xcert = await Xcert.new('Foo', 'F');
await xcert.mint(accounts[0], id1, mockProof, 'url1');
});

it('destroys NFToken id 1', async () => {
await xcert.mint(accounts[0], id1, mockProof, 'url1');
await xcert.burn(id1);
const count = await xcert.balanceOf(accounts[0]);
assert.equal(count, 0);
});

it('reverts trying to transfer when transfers are disabled', async () => {
await xcert.mint(accounts[0], id1, mockProof, 'url1');
await xcert.setTransferable(false);
await assertRevert(xcert.transferFrom(accounts[0], accounts[1], id1));
});

it('correctly chains additional proof', async () => {
await xcert.chain(id1, mockProof2);
var proof = await xcert.getProof(id1);
assert.equal(proof, mockProof2);
});

});
43 changes: 43 additions & 0 deletions test/utils/Selector.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
const Xcert = artifacts.require('Xcert');
const BurnableXcert = artifacts.require('BurnableXcert');
const ChainableXcert = artifacts.require('ChainableXcert');
const SettableTransferXcert = artifacts.require('SettableTransferXcert');
const Selector = artifacts.require('Selector');

contract('Selector', (accounts) => {

let selector;

beforeEach(async function () {
selector = await Selector.new();
});

it('Checks Xcert selector', async () => {
var xcert = await Xcert.new('Foo', 'F');
var bytes = await selector.calculateXcertSelector();
var supports = await xcert.supportsInterface(bytes);
assert.equal(supports, true);
});

it('Checks BurnableXcert selector', async () => {
var xcert = await BurnableXcert.new('Foo', 'F');
var bytes = await selector.calculateBurnableXcertSelector();
var supports = await xcert.supportsInterface(bytes);
assert.equal(supports, true);
});

it('Checks SettableTransferXcert selector', async () => {
var xcert = await SettableTransferXcert.new('Foo', 'F');
var bytes = await selector.calculateSettableTransferXcertSelector();
var supports = await xcert.supportsInterface(bytes);
assert.equal(supports, true);
});

it('Checks ChainableXcert selector', async () => {
var xcert = await ChainableXcert.new('Foo', 'F');
var bytes = await selector.calculateChainableXcertSelector();
var supports = await xcert.supportsInterface(bytes);
assert.equal(supports, true);
});

});

0 comments on commit 084a1f8

Please sign in to comment.