├── .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 |
--------------------------------------------------------------------------------