Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New token structure #360

Merged
merged 28 commits into from
Jan 20, 2020
Merged

New token structure #360

merged 28 commits into from
Jan 20, 2020

Conversation

kosecki123
Copy link
Contributor

@kosecki123 kosecki123 commented Dec 11, 2019

New Token structure based on ERC-1888

Our current certificate structure is based on ERC-721 non-fungible tokens. This presents an issue when a part of a certificate's volume has to be transferred to another owner.
In cases like these, we currently "split" the certificate into 2 smaller certificates, and then transfer one of the certificates to the new owner, and leave the original certificate to the original owner - deprecating the old certificate.
This approach is not ideal, so we started looking into better ways of changing owners for smaller parts of the certificates.

Decision

We decided to use the ERC-1888 Certificate structure so that we can comply and work on standardizing Certificates.

Consequences

We would no longer need to split certificates and lose the certificate history whenever we want to transfer a part of the certificate to a new owner.

Implemented features

  • Public Certificate issuance, approval, transfer, claim
  • Private issuance - Partially implemented but missing key things

@greg-flexidao
Copy link

Nice job @kosecki123!
I see you doing 4 things here:

  1. approval of each action issue/claim/transfer
  2. as I understand you want to make it NFT
  3. make issuance and claims private
  4. reveal the private issuance/claim into a "normal" certificate as you wrote in one TODO: zk proofs that issuance commitment - revealed claims < toBeRevealed claim

What would you say if we would make proposed improvements modular that sit on top of proposed standard for clarity (examples):

  1. approval is a separate contract (can be inherited by the global registry) or consider that permissioning and request potentially can be solved in a clean way with just identity (Certifying Authority) where you send execution request (i.e. based on ERC-735), and with right key can check and approve that call, this way will leave room for future improvements for that functionality.

      1. as I understand you want to make it NFT, but with value = X MWh, where X is hidden within commitment and where each action creates a verifiable commitment that then can fallback to / be exchangeable to ERC-1888 (NFT+FT)?
  2. "privateIssuance", "privateTransfer" and "privateClaim" can be used in a separate contract sitting on top of the ERC-1888 and fall back to "normal" certificate when needed? As this would require custom circut (remember about 2 different balances), perhaps we can assume that only "privateIssuance", "privateTransfer" are needed (and therefore only balance will be private) and when you claim you actually want to reveal the value (claimedBalance)?

Current draft to be compliant with underlying ERC-1155 needs following:

  • the (NFT) token has to have balance/value 1, when minted
  • the token has to be transfered from 0x00 to owner

Regarding compliance with ERC-1888:
claim = transfer from owner to 0x00, decrease balance, increase claimedBalance
Claim according to ERC-1888 aim to eventually make the certificates non-transferable (certificates have 2 balances, balance and claimedBalance), but with claimed balance in the state to allow for automation.
I don't understand what do you mean by claim in your draft?

Awesome work!

@greg-flexidao
Copy link

Also you while for your preciseProofs the order is important (as there is a strict scheme) in this case you want to just store balances (order is not important ?), therefore you will need simple merkle proof (without specifying which side of the branch is that), and you can get rid of boolean left and use openzeppelin's verification of merkle proof.

https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/cryptography/MerkleProof.sol

@greg-flexidao
Copy link

The reason for splitting the private and public functionalities is that, usually the privacy schemes work on a basis of a separate layer where you deposit the tokens to a smart contract from where you can privately move it and then later withdraw it when needed...

https://ethresear.ch/t/ethereum-9-send-erc20-privately-using-mimblewimble-and-zk-snarks/6217

@josipbagaric josipbagaric marked this pull request as ready for review January 17, 2020 10:35
'0'
)
],
toBlock: undefined
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please make sure fromBlock is passed (even if it's 0, so it works on Volta).

Also, maybe instead of toBlock undefined it's better to say toBlock: 'latest'?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was copied from old Certificate.ts, will update.

'0'
)
],
toBlock: undefined
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider fromBlock: 0/toBlock latest

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was copied from old Certificate.ts, will update.

from,
to,
parseInt(this.id, 10),
Math.round(amount),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the reason for rounding here?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's no way to transfer a part of a token in "ERC20". This rounds it to avoid a revert, but you're right, this might not be desired behaviour.

approved: boolean;
initialized: boolean;

constructor(id: string, configuration: Configuration.Entity) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Constructor could be removed if initialized declaration would declare its value as well.


private data: number[];

constructor(id: string, configuration: Configuration.Entity) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Constructor could be removed if initialized declaration would declare its value as well.

Aka

public initialized = false

};
});

it('issuer initializes the supply', async () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Empty test

@@ -0,0 +1,229 @@
// pragma solidity ^0.5.0;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file can be removed.

@josipbagaric josipbagaric merged commit e36a5a3 into master Jan 20, 2020
@josipbagaric josipbagaric deleted the feat/new-token-structure branch January 20, 2020 13:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants