Skip to content

Instantly share code, notes, and snippets.

@recmo
Created January 30, 2019 21:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save recmo/ec5b39e4cfc047df7629eb13c27034f1 to your computer and use it in GitHub Desktop.
Save recmo/ec5b39e4cfc047df7629eb13c27034f1 to your computer and use it in GitHub Desktop.
ShardToken: Actor Model through Cousin Proofs
contract ShardToken {
address OWNER;
address ROOT;
uint256[] ANCESTRY_PROOF;
address owner;
uint256 next_nonce;
uint256 balance;
mapping (address => uint256) allowance;
modifier only_owner() {
require(msg.sender == OWNER, "ONLY_OWNER");
}
modifier only_relatives(uint256[] memory proof) {
require(related(msg.sender, proof), "NOT_RELATED");
}
constructor(
address owner,
address root,
uint256[] ancestry_proof,
uint amount)
{
OWNER = owner;
ANCESTRY_PROOF = ancestry_proof;
next_nonce = 0;
//
assert(related(this, ANCESTRY_PROOF), "INVALID_PROOF");
}
// Allows anyone to create a new empty wallet for this
// token.
function create()
public
returns (address new_wallet)
{
address owner = msg.sender;
uint256 nonce = next_nonce;
next_nonce += 1;
new_wallet = new ShardToken(
owner,
ROOT,
ANCESTRY_PROOF + [next_nonce],
amount
);
assert(new_wallet == child_address(this, child_nonce));
}
function destroy()
public
only_owner()
{
}
// Transfer to some other wallet
function transfer(
ShardToken receipient,
uint256 amount
)
public
only_owner()
{
require(balance > amount, "INSUFFICIENT_FUNDS");
balance -= amount;
receipient.receive(amount, ANCESTRY_PROOF);
}
function receive(
uint256 amount,
uint256[] ancestry_proof
)
public
only_relatives(ancestry_proof)
{
balance += amount;
// Should not happen because total supply guarantees an upper limit.
assert(balance > amount, "BALANCE_OVERFLOW");
}
/// Check if a given contract is a sibbling
/// @param sibbling The constract address to check for familiar ties.
/// @param nonces Claimed proof of ancenstry.
function related(
address sibbling,
uint256[] nonces
)
internal pure
returns (bool)
{
address relative = ROOT;
for (uint256 i = 0; i < nonces.length; ++i) {
relative = child_address(relative, nonces[i]);
}
return relative == sibbling;
}
// Todo:
// https://github.com/projectchicago/gastoken/blob/master/contract/rlp.sol#L21
function child_address(
address parent,
uint256 nonce
)
internal pure
returns (address)
{
bytes32 code_hash = code_hash(this);
bytes32 hash = keccak256(abi.encodePacked(
bytes1(0xff),
parent,
nonce,
code_hash
));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment