diff --git a/python/okota/accounts_index/accounts_index.py b/python/okota/accounts_index/accounts_index.py index d3d7387..a132ad8 100644 --- a/python/okota/accounts_index/accounts_index.py +++ b/python/okota/accounts_index/accounts_index.py @@ -40,7 +40,7 @@ class AccountsIndexAddressDeclarator(AccountsIndex): @staticmethod def gas(code=None): - return 700000 + return 1500000 def constructor(self, sender_address, context_address, address_declarator_address): diff --git a/python/okota/accounts_index/runnable/deploy.py b/python/okota/accounts_index/runnable/deploy.py index 68fb2b0..dfff1e7 100644 --- a/python/okota/accounts_index/runnable/deploy.py +++ b/python/okota/accounts_index/runnable/deploy.py @@ -17,6 +17,10 @@ import chainlib.eth.cli from chainlib.chain import ChainSpec from chainlib.eth.connection import EthHTTPConnection from chainlib.eth.tx import receipt +from chainlib.eth.address import ( + is_checksum_address, + is_address, + ) # local imports from okota.accounts_index import AccountsIndexAddressDeclarator diff --git a/python/okota/data/AccountsIndexAddressDeclarator.bin b/python/okota/data/AccountsIndexAddressDeclarator.bin index 8d0f1ab..12021e4 100644 --- a/python/okota/data/AccountsIndexAddressDeclarator.bin +++ b/python/okota/data/AccountsIndexAddressDeclarator.bin @@ -1 +1 @@ -60806040523480156200001157600080fd5b5060405162000ace38038062000ace8339818101604052810190620000379190620001d9565b606033600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550826000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040516020016200012e9190620002b3565b60405160208183030381529060405290506002816040516200015191906200029a565b602060405180830381855afa1580156200016f573d6000803e3d6000fd5b5050506040513d601f19601f8201168201806040525081019062000194919062000220565b600181905550600160048190555050505062000393565b600081519050620001bc816200035f565b92915050565b600081519050620001d38162000379565b92915050565b60008060408385031215620001f357620001f26200035a565b5b60006200020385828601620001ab565b92505060206200021685828601620001ab565b9150509250929050565b6000602082840312156200023957620002386200035a565b5b60006200024984828501620001c2565b91505092915050565b6200025d81620002e6565b82525050565b60006200027082620002d0565b6200027c8185620002db565b93506200028e81856020860162000324565b80840191505092915050565b6000620002a8828462000263565b915081905092915050565b6000602082019050620002ca600083018462000252565b92915050565b600081519050919050565b600081905092915050565b6000620002f38262000304565b9050919050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60005b838110156200034457808201518184015260208101905062000327565b8381111562000354576000848401525b50505050565b600080fd5b6200036a81620002e6565b81146200037657600080fd5b50565b6200038481620002fa565b81146200039057600080fd5b50565b61072b80620003a36000396000f3fe608060405234801561001057600080fd5b5060043610610074576000357c0100000000000000000000000000000000000000000000000000000000900480630a3b0a4f14610079578063370f91fb146100a95780633ef25013146100c75780638da5cb5b146100f75780639d76ea5814610115575b600080fd5b610093600480360381019061008e9190610496565b610133565b6040516100a0919061057c565b60405180910390f35b6100b16103c6565b6040516100be9190610538565b60405180910390f35b6100e160048036038101906100dc9190610496565b6103ec565b6040516100ee919061057c565b60405180910390f35b6100ff610437565b60405161010c9190610538565b60405180910390f35b61011d61045d565b60405161012a9190610538565b60405180910390f35b60008060606000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1685600154604051602401610188929190610553565b6040516020818303038152906040527fae47ece0000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516102129190610521565b6000604051808303816000865af19150503d806000811461024f576040519150601f19603f3d011682016040523d82523d6000602084013e610254565b606091505b5080935081945050508261026757600080fd5b60017f01000000000000000000000000000000000000000000000000000000000000000282601f8151811061029f5761029e6106aa565b5b60200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461031557600080fd5b600454905080600360008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506004600081548092919061037190610632565b9190505550808573ffffffffffffffffffffffffffffffffffffffff167f9cc987676e7d63379f176ea50df0ae8d2d9d1141d1231d4ce15b5965f73c943060405160405180910390a360019350505050919050565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600080600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054119050919050565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600081359050610490816106de565b92915050565b6000602082840312156104ac576104ab6106d9565b5b60006104ba84828501610481565b91505092915050565b6104cc816105ad565b82525050565b6104db816105bf565b82525050565b6104ea816105cb565b82525050565b60006104fb82610597565b61050581856105a2565b93506105158185602086016105ff565b80840191505092915050565b600061052d82846104f0565b915081905092915050565b600060208201905061054d60008301846104c3565b92915050565b600060408201905061056860008301856104c3565b61057560208301846104e1565b9392505050565b600060208201905061059160008301846104d2565b92915050565b600081519050919050565b600081905092915050565b60006105b8826105d5565b9050919050565b60008115159050919050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b60005b8381101561061d578082015181840152602081019050610602565b8381111561062c576000848401525b50505050565b600061063d826105f5565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156106705761066f61067b565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600080fd5b6106e7816105ad565b81146106f257600080fd5b5056fea26469706673582212201f78efc5447ec317cfce0b750b61e3d42cfebbea205576a2e8924af71a2492d364736f6c63430008070033 \ No newline at end of file +60806040523480156200001157600080fd5b506040516200126738038062001267833981810160405281019062000037919062000235565b606033600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550826000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040516020016200012e91906200030f565b6040516020818303038152906040529050600281604051620001519190620002f6565b602060405180830381855afa1580156200016f573d6000803e3d6000fd5b5050506040513d601f19601f820116820180604052508101906200019491906200027c565b600181905550600560009080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505050620003ef565b6000815190506200021881620003bb565b92915050565b6000815190506200022f81620003d5565b92915050565b600080604083850312156200024f576200024e620003b6565b5b60006200025f8582860162000207565b9250506020620002728582860162000207565b9150509250929050565b600060208284031215620002955762000294620003b6565b5b6000620002a5848285016200021e565b91505092915050565b620002b98162000342565b82525050565b6000620002cc826200032c565b620002d8818562000337565b9350620002ea81856020860162000380565b80840191505092915050565b6000620003048284620002bf565b915081905092915050565b6000602082019050620003266000830184620002ae565b92915050565b600081519050919050565b600081905092915050565b60006200034f8262000360565b9050919050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60005b83811015620003a057808201518184015260208101905062000383565b83811115620003b0576000848401525b50505050565b600080fd5b620003c68162000342565b8114620003d257600080fd5b50565b620003e08162000356565b8114620003ec57600080fd5b50565b610e6880620003ff6000396000f3fe608060405234801561001057600080fd5b50600436106100c6576000357c01000000000000000000000000000000000000000000000000000000009004806379ba50971161008e57806379ba5097146101975780638da5cb5b146101b55780639d76ea58146101d3578063da2824a8146101f1578063e2095c0714610221578063f2fde38b14610251576100c6565b80630a3b0a4f146100cb5780630cbb0f83146100fb578063370f91fb146101195780633ef25013146101375780635ae06f7e14610167575b600080fd5b6100e560048036038101906100e09190610b24565b610281565b6040516100f29190610c46565b60405180910390f35b610103610610565b6040516101109190610c61565b60405180910390f35b610121610629565b60405161012e9190610c02565b60405180910390f35b610151600480360381019061014c9190610b24565b61064f565b60405161015e9190610c46565b60405180910390f35b610181600480360381019061017c9190610b24565b61069a565b60405161018e9190610c46565b60405180910390f35b61019f61074e565b6040516101ac9190610c46565b60405180910390f35b6101bd6108f9565b6040516101ca9190610c02565b60405180910390f35b6101db61091f565b6040516101e89190610c02565b60405180910390f35b61020b60048036038101906102069190610b24565b610943565b6040516102189190610c46565b60405180910390f35b61023b60048036038101906102369190610b51565b610a00565b6040516102489190610c02565b60405180910390f35b61026b60048036038101906102669190610b24565b610a54565b6040516102789190610c46565b60405180910390f35b60008060606000600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff166102de57600080fd5b6000600360008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541461032a57600080fd5b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1685600154604051602401610378929190610c1d565b6040516020818303038152906040527fae47ece0000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040516104029190610beb565b6000604051808303816000865af19150503d806000811461043f576040519150601f19603f3d011682016040523d82523d6000602084013e610444565b606091505b5080935081945050508261045757600080fd5b60017f01000000000000000000000000000000000000000000000000000000000000000282601f8151811061048f5761048e610dd0565b5b60200101517f010000000000000000000000000000000000000000000000000000000000000090047f0100000000000000000000000000000000000000000000000000000000000000027effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161461050557600080fd5b60016005805490506105179190610ce8565b905080600360008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055506005859080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808573ffffffffffffffffffffffffffffffffffffffff167f9cc987676e7d63379f176ea50df0ae8d2d9d1141d1231d4ce15b5965f73c943060405160405180910390a360019350505050919050565b600060016005805490506106249190610ce8565b905090565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600080600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054119050919050565b60003373ffffffffffffffffffffffffffffffffffffffff16600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146106f657600080fd5b600460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81549060ff021916905560019050919050565b600080600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146107ab57600080fd5b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506000600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3600191505090565b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60003373ffffffffffffffffffffffffffffffffffffffff16600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461099f57600080fd5b6001600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555060019050919050565b60006005600183610a119190610c92565b81548110610a2257610a21610dd0565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610ab057600080fd5b81600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060019050919050565b600081359050610b0981610e04565b92915050565b600081359050610b1e81610e1b565b92915050565b600060208284031215610b3a57610b39610dff565b5b6000610b4884828501610afa565b91505092915050565b600060208284031215610b6757610b66610dff565b5b6000610b7584828501610b0f565b91505092915050565b610b8781610d1c565b82525050565b610b9681610d2e565b82525050565b610ba581610d3a565b82525050565b6000610bb682610c7c565b610bc08185610c87565b9350610bd0818560208601610d6e565b80840191505092915050565b610be581610d64565b82525050565b6000610bf78284610bab565b915081905092915050565b6000602082019050610c176000830184610b7e565b92915050565b6000604082019050610c326000830185610b7e565b610c3f6020830184610b9c565b9392505050565b6000602082019050610c5b6000830184610b8d565b92915050565b6000602082019050610c766000830184610bdc565b92915050565b600081519050919050565b600081905092915050565b6000610c9d82610d64565b9150610ca883610d64565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115610cdd57610cdc610da1565b5b828201905092915050565b6000610cf382610d64565b9150610cfe83610d64565b925082821015610d1157610d10610da1565b5b828203905092915050565b6000610d2782610d44565b9050919050565b60008115159050919050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b60005b83811015610d8c578082015181840152602081019050610d71565b83811115610d9b576000848401525b50505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600080fd5b610e0d81610d1c565b8114610e1857600080fd5b50565b610e2481610d64565b8114610e2f57600080fd5b5056fea2646970667358221220e9a12fd1de81e2bcbb0972ae6ad9617b5a9f3b63f3110ba56f6681ea3907456064736f6c63430008070033 \ No newline at end of file diff --git a/python/okota/data/AccountsIndexAddressDeclarator.json b/python/okota/data/AccountsIndexAddressDeclarator.json index 0c04d04..216bec4 100644 --- a/python/okota/data/AccountsIndexAddressDeclarator.json +++ b/python/okota/data/AccountsIndexAddressDeclarator.json @@ -1 +1 @@ -[{"inputs":[{"internalType":"address","name":"_tokenAddress","type":"address"},{"internalType":"address","name":"_addressDeclaratorAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"addedAccount","type":"address"},{"indexed":true,"internalType":"uint256","name":"accountIndex","type":"uint256"}],"name":"AddressAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"add","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"addressDeclaratorAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"have","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}] +[{"inputs":[{"internalType":"address","name":"_tokenAddress","type":"address"},{"internalType":"address","name":"_addressDeclaratorAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"addedAccount","type":"address"},{"indexed":true,"internalType":"uint256","name":"accountIndex","type":"uint256"}],"name":"AddressAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"acceptOwnership","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"add","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_writer","type":"address"}],"name":"addWriter","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"addressDeclaratorAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_writer","type":"address"}],"name":"deleteWriter","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_idx","type":"uint256"}],"name":"entry","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"entryCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"have","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}] diff --git a/python/setup.cfg b/python/setup.cfg index 42eafbc..9f1c3ec 100644 --- a/python/setup.cfg +++ b/python/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = okota -version = 0.2.4a6 +version = 0.2.4a14 description = Registries for CIC using the eth-address-index backend author = Louis Holbrook author_email = dev@holbrook.no diff --git a/solidity/AccountsIndexAddressDeclarator.sol b/solidity/AccountsIndexAddressDeclarator.sol index 8f7bc90..69482bd 100644 --- a/solidity/AccountsIndexAddressDeclarator.sol +++ b/solidity/AccountsIndexAddressDeclarator.sol @@ -3,13 +3,16 @@ pragma solidity >0.6.11; // SPDX-License-Identifier: GPL-3.0-or-later +// TODO: inherit accounts index contract contract AccountsIndexAddressDeclarator { address public tokenAddress; bytes32 tokenAddressHash; address public addressDeclaratorAddress; mapping(address => uint256) entryIndex; - uint256 count; + //uint256 count; + mapping(address => bool) writers; + address[] entries; address public owner; address newOwner; @@ -24,7 +27,7 @@ contract AccountsIndexAddressDeclarator { tokenAddress = _tokenAddress; _tokenAddressPadded = abi.encode(tokenAddress); tokenAddressHash = sha256(_tokenAddressPadded); - count = 1; + entries.push(address(0)); } function add(address _account) external returns (bool) { @@ -32,19 +35,64 @@ contract AccountsIndexAddressDeclarator { bytes memory r; uint256 oldEntryIndex; + require(writers[msg.sender]); + require(entryIndex[_account] == 0); + (ok, r) = addressDeclaratorAddress.call(abi.encodeWithSignature("addDeclaration(address,bytes32)", _account, tokenAddressHash)); require(ok); require(r[31] == 0x01); - oldEntryIndex = count; + oldEntryIndex = entries.length - 1; entryIndex[_account] = oldEntryIndex; - count++; + entries.push(_account); emit AddressAdded(_account, oldEntryIndex); return true; } + // Implements AccountsIndex function have(address _account) external view returns (bool) { return entryIndex[_account] > 0; } + + // Implements AccountsIndex + function entry(uint256 _idx) public returns (address) { + return entries[_idx+1]; + } + + // Implements AccountsIndex + function entryCount() public returns (uint256) { + return entries.length - 1; + } + + function addWriter(address _writer) public returns (bool) { + require(owner == msg.sender); + writers[_writer] = true; + return true; + } + + function deleteWriter(address _writer) public returns (bool) { + require(owner == msg.sender); + delete writers[_writer]; + return true; + } + + // Implements EIP173 + function transferOwnership(address _newOwner) public returns (bool) { + require(msg.sender == owner); + newOwner = _newOwner; + return true; + } + + // Implements OwnedAccepter + function acceptOwnership() public returns (bool) { + address oldOwner; + + require(msg.sender == newOwner); + oldOwner = owner; + owner = newOwner; + newOwner = address(0); + emit OwnershipTransferred(oldOwner, owner); + return true; + } }