├── .gitignore ├── README.md ├── app ├── index.html ├── javascripts │ └── app.js └── stylesheets │ └── app.css ├── contracts ├── ConvertLib.sol ├── MetaCoin.sol ├── Migrations.sol ├── ProofOfExistence1.sol ├── ProofOfExistence2.sol └── ProofOfExistence3.sol ├── migrations ├── 1_initial_migration.js └── 2_deploy_contracts.js ├── test └── metacoin.js └── truffle.js /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | *.swp 3 | *.swo 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # solidity-experiments 2 | Solidity experiments 3 | -------------------------------------------------------------------------------- /app/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | MetaCoin - Default Truffle App 5 | 6 | 7 | 8 | 9 | 10 |

MetaCoin

11 |

Example Truffle Dapp

12 |

You have META

13 | 14 |
15 |

Send

16 |
17 |
18 |

19 |

20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /app/javascripts/app.js: -------------------------------------------------------------------------------- 1 | var accounts; 2 | var account; 3 | var balance; 4 | 5 | function setStatus(message) { 6 | var status = document.getElementById("status"); 7 | status.innerHTML = message; 8 | }; 9 | 10 | function refreshBalance() { 11 | var meta = MetaCoin.deployed(); 12 | 13 | meta.getBalance.call(account, {from: account}).then(function(value) { 14 | var balance_element = document.getElementById("balance"); 15 | balance_element.innerHTML = value.valueOf(); 16 | }).catch(function(e) { 17 | console.log(e); 18 | setStatus("Error getting balance; see log."); 19 | }); 20 | }; 21 | 22 | function sendCoin() { 23 | var meta = MetaCoin.deployed(); 24 | 25 | var amount = parseInt(document.getElementById("amount").value); 26 | var receiver = document.getElementById("receiver").value; 27 | 28 | setStatus("Initiating transaction... (please wait)"); 29 | 30 | meta.sendCoin(receiver, amount, {from: account}).then(function() { 31 | setStatus("Transaction complete!"); 32 | refreshBalance(); 33 | }).catch(function(e) { 34 | console.log(e); 35 | setStatus("Error sending coin; see log."); 36 | }); 37 | }; 38 | 39 | window.onload = function() { 40 | web3.eth.getAccounts(function(err, accs) { 41 | if (err != null) { 42 | alert("There was an error fetching your accounts."); 43 | return; 44 | } 45 | 46 | if (accs.length == 0) { 47 | alert("Couldn't get any accounts! Make sure your Ethereum client is configured correctly."); 48 | return; 49 | } 50 | 51 | accounts = accs; 52 | account = accounts[0]; 53 | 54 | refreshBalance(); 55 | }); 56 | } 57 | -------------------------------------------------------------------------------- /app/stylesheets/app.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin-left: 25%; 3 | margin-right: 25%; 4 | margin-top: 10%; 5 | font-family: "Open Sans", sans-serif; 6 | } 7 | 8 | label { 9 | display: inline-block; 10 | width: 100px; 11 | } 12 | 13 | input { 14 | width: 500px; 15 | padding: 5px; 16 | font-size: 16px; 17 | } 18 | 19 | button { 20 | font-size: 16px; 21 | padding: 5px; 22 | } 23 | 24 | h1, h2 { 25 | display: inline-block; 26 | vertical-align: middle; 27 | margin-top: 0px; 28 | margin-bottom: 10px; 29 | } 30 | 31 | h2 { 32 | color: #AAA; 33 | font-size: 32px; 34 | } 35 | 36 | h3 { 37 | font-weight: normal; 38 | color: #AAA; 39 | font-size: 24px; 40 | } 41 | 42 | .black { 43 | color: black; 44 | } 45 | 46 | #balance { 47 | color: black; 48 | } 49 | -------------------------------------------------------------------------------- /contracts/ConvertLib.sol: -------------------------------------------------------------------------------- 1 | library ConvertLib{ 2 | function convert(uint amount,uint conversionRate) returns (uint convertedAmount) 3 | { 4 | return amount * conversionRate; 5 | } 6 | } -------------------------------------------------------------------------------- /contracts/MetaCoin.sol: -------------------------------------------------------------------------------- 1 | import "./ConvertLib.sol"; 2 | 3 | // This is just a simple example of a coin-like contract. 4 | // It is not standards compatible and cannot be expected to talk to other 5 | // coin/token contracts. If you want to create a standards-compliant 6 | // token, see: https://github.com/ConsenSys/Tokens. Cheers! 7 | 8 | contract MetaCoin { 9 | mapping (address => uint) balances; 10 | 11 | function MetaCoin() { 12 | balances[tx.origin] = 10000; 13 | } 14 | 15 | function sendCoin(address receiver, uint amount) returns(bool sufficient) { 16 | if (balances[msg.sender] < amount) return false; 17 | balances[msg.sender] -= amount; 18 | balances[receiver] += amount; 19 | return true; 20 | } 21 | 22 | function getBalanceInEth(address addr) returns(uint){ 23 | return ConvertLib.convert(getBalance(addr),2); 24 | } 25 | 26 | function getBalance(address addr) returns(uint) { 27 | return balances[addr]; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /contracts/Migrations.sol: -------------------------------------------------------------------------------- 1 | contract Migrations { 2 | address public owner; 3 | uint public last_completed_migration; 4 | 5 | modifier restricted() { 6 | if (msg.sender == owner) _; 7 | } 8 | 9 | function Migrations() { 10 | owner = msg.sender; 11 | } 12 | 13 | function setCompleted(uint completed) restricted { 14 | last_completed_migration = completed; 15 | } 16 | 17 | function upgrade(address new_address) restricted { 18 | Migrations upgraded = Migrations(new_address); 19 | upgraded.setCompleted(last_completed_migration); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /contracts/ProofOfExistence1.sol: -------------------------------------------------------------------------------- 1 | // Proof of Existence contract, version 1 2 | contract ProofOfExistence1 { 3 | // state 4 | bytes32 public proof; 5 | 6 | 7 | // constructor 8 | function ProofOfExistence() { 9 | } 10 | 11 | 12 | // calculate and store the proof for a document 13 | function notarize(string document) { 14 | proof = calculateProof(document); 15 | } 16 | 17 | // helper function to get a document's sha256 18 | function calculateProof(string document) returns (bytes32) { 19 | return sha256(document); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /contracts/ProofOfExistence2.sol: -------------------------------------------------------------------------------- 1 | // Proof of Existence contract, version 2 2 | contract ProofOfExistence2 { 3 | // state 4 | bytes32[] proofs; 5 | 6 | 7 | // store a proof of existence in the contract state 8 | // *transactional function* 9 | function storeProof(bytes32 proof) { 10 | if (proofs.length >= 255) { throw; } 11 | proofs.push(proof); 12 | } 13 | 14 | // calculate and store the proof for a document 15 | // *transactional function* 16 | function notarize(string document) { 17 | var proof = calculateProof(document); 18 | storeProof(proof); 19 | } 20 | 21 | // helper function to get a document's sha256 22 | // *read-only function* 23 | function calculateProof(string document) returns (bytes32) { 24 | return sha256(document); 25 | } 26 | 27 | // check if a document has been notarized 28 | // *read-only function* 29 | function checkDocument(string document) returns (bool) { 30 | var proof = calculateProof(document); 31 | return hasProof(proof); 32 | } 33 | 34 | // returns true if proof is stored 35 | // *read-only function* 36 | function hasProof(bytes32 proof) returns (bool) { 37 | for (uint8 i = 0; i < proofs.length; i++) { 38 | if (proofs[i] == proof) { 39 | return true; 40 | } 41 | } 42 | return false; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /contracts/ProofOfExistence3.sol: -------------------------------------------------------------------------------- 1 | // Proof of Existence contract, version 3 2 | contract ProofOfExistence3 { 3 | 4 | mapping (bytes32 => bool) proofs; 5 | 6 | // store a proof of existence in the contract state 7 | function storeProof(bytes32 proof) { 8 | proofs[proof] = true; 9 | } 10 | 11 | // calculate and store the proof for a document 12 | function notarize(string document) { 13 | var proof = calculateProof(document); 14 | storeProof(proof); 15 | } 16 | 17 | // helper function to get a document's sha256 18 | function calculateProof(string document) returns (bytes32) { 19 | return sha256(document); 20 | } 21 | 22 | // check if a document has been notarized 23 | function checkDocument(string document) returns (bool) { 24 | var proof = calculateProof(document); 25 | return hasProof(proof); 26 | } 27 | 28 | // returns true if proof is stored 29 | function hasProof(bytes32 proof) returns (bool) { 30 | return proofs[proof]; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /migrations/1_initial_migration.js: -------------------------------------------------------------------------------- 1 | module.exports = function(deployer) { 2 | deployer.deploy(Migrations); 3 | }; 4 | -------------------------------------------------------------------------------- /migrations/2_deploy_contracts.js: -------------------------------------------------------------------------------- 1 | module.exports = function(deployer) { 2 | deployer.deploy(ProofOfExistence1); 3 | deployer.deploy(ProofOfExistence2); 4 | deployer.deploy(ProofOfExistence3); 5 | }; 6 | -------------------------------------------------------------------------------- /test/metacoin.js: -------------------------------------------------------------------------------- 1 | contract('MetaCoin', function(accounts) { 2 | it("should put 10000 MetaCoin in the first account", function() { 3 | var meta = MetaCoin.deployed(); 4 | 5 | return meta.getBalance.call(accounts[0]).then(function(balance) { 6 | assert.equal(balance.valueOf(), 10000, "10000 wasn't in the first account"); 7 | }); 8 | }); 9 | it("should call a function that depends on a linked library ", function(){ 10 | var meta = MetaCoin.deployed(); 11 | var metaCoinBalance; 12 | var metaCoinEthBalance; 13 | 14 | return meta.getBalance.call(accounts[0]).then(function(outCoinBalance){ 15 | metaCoinBalance = outCoinBalance.toNumber(); 16 | return meta.getBalanceInEth.call(accounts[0]); 17 | }).then(function(outCoinBalanceEth){ 18 | metaCoinEthBalance = outCoinBalanceEth.toNumber(); 19 | 20 | }).then(function(){ 21 | assert.equal(metaCoinEthBalance,2*metaCoinBalance,"Library function returned unexpeced function, linkage may be broken"); 22 | 23 | }); 24 | }); 25 | it("should send coin correctly", function() { 26 | var meta = MetaCoin.deployed(); 27 | 28 | // Get initial balances of first and second account. 29 | var account_one = accounts[0]; 30 | var account_two = accounts[1]; 31 | 32 | var account_one_starting_balance; 33 | var account_two_starting_balance; 34 | var account_one_ending_balance; 35 | var account_two_ending_balance; 36 | 37 | var amount = 10; 38 | 39 | return meta.getBalance.call(account_one).then(function(balance) { 40 | account_one_starting_balance = balance.toNumber(); 41 | return meta.getBalance.call(account_two); 42 | }).then(function(balance) { 43 | account_two_starting_balance = balance.toNumber(); 44 | return meta.sendCoin(account_two, amount, {from: account_one}); 45 | }).then(function() { 46 | return meta.getBalance.call(account_one); 47 | }).then(function(balance) { 48 | account_one_ending_balance = balance.toNumber(); 49 | return meta.getBalance.call(account_two); 50 | }).then(function(balance) { 51 | account_two_ending_balance = balance.toNumber(); 52 | 53 | assert.equal(account_one_ending_balance, account_one_starting_balance - amount, "Amount wasn't correctly taken from the sender"); 54 | assert.equal(account_two_ending_balance, account_two_starting_balance + amount, "Amount wasn't correctly sent to the receiver"); 55 | }); 56 | }); 57 | }); 58 | -------------------------------------------------------------------------------- /truffle.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | build: { 3 | "index.html": "index.html", 4 | "app.js": [ 5 | "javascripts/app.js" 6 | ], 7 | "app.css": [ 8 | "stylesheets/app.css" 9 | ], 10 | "images/": "images/" 11 | }, 12 | rpc: { 13 | host: "localhost", 14 | port: 8545 15 | } 16 | }; 17 | --------------------------------------------------------------------------------