· 7 years ago · Mar 26, 2018, 09:12 PM
1pragma solidity ^0.4.0;
2
3/*
4 * Example of transacting across blockchains. Requires both blockchains can implement the contract below.
5 *
6 * In this example Bob wants to buy 10 ETH for 1 BTC and Alice takes him up on the deal. The deal is made
7 * outside of this contract - the contract is used only to secure the exchange.
8 *
9 * 1. Bob creates a BTC contract with 1 BTC and the public part of a secret key
10 * 2. Alice creates an ETH contract with 10 ETH
11 * 3. Alice locks Bob's BTC contract by sending it her BTC address and the address of her ETH contract
12 * 4. Alice locks her contract by giving it the public part of Bob's secret key
13 * 5. Bob checks Alice's ETH contract to make sure it is locked with the public part of his secret key
14 * and that he agrees with her side of the deal.
15 * 6. Bob collects his 10 ETH by sending Alice's contract his ETH address and the secret part of his key
16 * 7. Now that Bob's secret key is public, Alice collects her 1 BTC by sending the secret key to Bob's contract
17 *
18 */
19
20contract TransactionExchangeContract {
21
22
23 // option 1: owner locks other persons contract then locks his with the other person's lock key
24 function lock( bytes32[] recipientsLockKey ) public;
25
26
27 // option 2: other person locks this contract with their contract address
28 function lock( address recipientAddress, address recipientContractAddress ) public;
29
30
31 // when the owner has locked the contract with just the recipient's lock key then the recipient
32 // can collect to any address provided the secret key is used
33 function collect( bytes32[] secretKey, address recipientAddress ) public;
34
35
36 // when the secret key is used to collect, the predefined recipient receives all funds in the contract
37 function collect( bytes32[] secretKey ) public;
38
39
40 // owner can cancel and have his funds returned if the contract has not been locked or else
41 // the lock time has been reached
42 function cancel() public;
43
44
45 // returns the value to be transacted
46 function value() public view returns (uint);
47
48}
49
50
51
52
53contract InterBlockchainTransaction is TransactionExchangeContract {
54
55 address public owner = msg.sender;
56 address public recipient = 0;
57 address public recipientContract = 0;
58
59 bytes32[] public lockKey;
60 bytes32[] public unlockKey;
61
62 bool public locked = false;
63 uint public locktime;
64 uint public lockedUntilBlock;
65
66
67 event Locked();
68
69
70 modifier onlyOwner {
71 require( msg.sender == owner );
72 _;
73 }
74
75
76 // construct with public part of secret key and fund contract with amount to exchange
77 function InterBlockchainTransaction( bytes32[] myLockKey, uint locktimeInBlocks ) public payable {
78 lockKey = myLockKey;
79 locktime = locktimeInBlocks;
80 }
81
82
83 // option 1: owner locks other persons contract then locks his with the other person's lock key
84 function lock( bytes32[] recipientsLockKey ) public onlyOwner{
85 require( ! locked );
86 lockKey = recipientsLockKey;
87 locked = true;
88 lockedUntilBlock = block.number + locktime;
89 emit Locked();
90 }
91
92
93 // option 2: other person locks this contract with their contract address
94 function lock( address recipientAddress, address recipientContractAddress ) public {
95 require( ! locked );
96 recipient = recipientAddress;
97 recipientContract = recipientContractAddress;
98 locked = true;
99 lockedUntilBlock = block.number + locktime;
100 emit Locked();
101 }
102
103
104 // when the owner has locked the contract with just the recipient's lock key then the recipient
105 // can collect to any address provided the secret key is used
106 function collect( bytes32[] secretKey, address recipientAddress ) public {
107 require( locked );
108 require( recipient == 0 );
109 recipient = recipientAddress;
110 collect( secretKey );
111 }
112
113
114 // when the secret key is used to collect, the predefined recipient receives all funds in the contract
115 function collect( bytes32[] secretKey ) public {
116 require( locked );
117 // TODO require( secretKey is secret part of lockKey );
118 // e.g. lockKey is a public key. secretKey is a signature of h, where h is a constant,
119 // say '0xac51e27c3fe38af1a0aeb2867a741ba6aa16780e435a586d934ccea3a71874b1'
120 // test is then: lockKey == ecrecover( h, secretKey.sigV, secretKey.sigR, secretKey.sigS );
121 // In this case the lockKey could be the owner's address
122 unlockKey = secretKey;
123 address myContract = this;
124 recipient.transfer( myContract.balance );
125 }
126
127
128 // owner can cancel and have his funds returned if the contract has not been locked or else
129 // the lock time has been reached
130 function cancel() public onlyOwner{
131 require( ! locked || (lockedUntilBlock < block.number) );
132 address myContract = this;
133 owner.transfer( myContract.balance );
134 }
135
136
137 // returns the value to be transacted
138 function value() public view returns (uint) {
139 address myContract = this;
140 return myContract.balance;
141 }
142
143
144}