Ethereum(12) - クラウドファンディング用のスマートコントラクト(キャンペーン成功・2回目)

前回、クラウドファンディング用のスマートコントラクトに対して、キャンペーンが成功するケースでテストしてみましたが、うまく動作しませんでした。

今回はその原因を調べてみます。

原因調査①

設定値を見直したところ1点、勘違いしていたことが分かりました。

それは設定値の締め切り(deadline)の単位は分ではなく秒ということです。

とりあえずこれだけ変更してもう一度トライしてみます。

デプロイ時の設定

デプロイ時(コンストラクタのコール時)の設定値は下記のように設定しました。

  • SELECT CONTRACT TO DEPLOY
    ‘Crowd Funding’を選択。
  • _duration
    テスト用に10分に設定。秒指定のため 600 を設定。
  • _goal amount
    目標額に20etherを設定。
    Mist Walletで設定する場合はwei表記のため 20000000000000000000 を設定。

[デプロイ時の設定値イメージ]

アカウントごとの役割

3つのアカウントの役割は前回同様です。

  • MAIN ACCOUNT (eth.accounts[0])
    オーナー
  • ACCOUNT1 (eth.accounts[1])
    投資家1
  • ACCOUNT2 (eth.accounts[2])
    投資家2

キャンペーンに成功するケース(2回目)

geth上でcfという変数に、スマートコントラクトを割り当てます。

アドレスとインタフェースはMist Walletから取得しておきます。

[コマンド]

1
var cf = eth.contract([ { "constant": false, "inputs": [], "name": "checkGoalReached", "outputs": [], "payable": false, "type": "function" }, { "constant": true, "inputs": [], "name": "ended", "outputs": [ { "name": "", "type": "bool", "value": false } ], "payable": false, "type": "function" }, { "constant": true, "inputs": [], "name": "numInvestors", "outputs": [ { "name": "", "type": "uint256", "value": "0" } ], "payable": false, "type": "function" }, { "constant": true, "inputs": [], "name": "totalAmount", "outputs": [ { "name": "", "type": "uint256", "value": "0" } ], "payable": false, "type": "function" }, { "constant": true, "inputs": [], "name": "status", "outputs": [ { "name": "", "type": "string", "value": "Funding" } ], "payable": false, "type": "function" }, { "constant": true, "inputs": [], "name": "goalAmount", "outputs": [ { "name": "", "type": "uint256", "value": "20000000000000000000" } ], "payable": false, "type": "function" }, { "constant": true, "inputs": [], "name": "deadline", "outputs": [ { "name": "", "type": "uint256", "value": "1625372072" } ], "payable": false, "type": "function" }, { "constant": true, "inputs": [ { "name": "", "type": "uint256" } ], "name": "investors", "outputs": [ { "name": "addr", "type": "address", "value": "0x0000000000000000000000000000000000000000" }, { "name": "amount", "type": "uint256", "value": "0" } ], "payable": false, "type": "function" }, { "constant": false, "inputs": [], "name": "kill", "outputs": [], "payable": false, "type": "function" }, { "constant": true, "inputs": [], "name": "owner", "outputs": [ { "name": "", "type": "address", "value": "0xec3b01f36b44182746ca109230567c4915512e35" } ], "payable": false, "type": "function" }, { "constant": false, "inputs": [], "name": "fund", "outputs": [], "payable": true, "type": "function" }, { "inputs": [ { "name": "_duration", "type": "uint256", "index": 0, "typeShort": "uint", "bits": "256", "displayName": "&thinsp;<span class=\"punctuation\">_</span>&thinsp;duration", "template": "elements_input_uint", "value": "600" }, { "name": "_goalAmount", "type": "uint256", "index": 1, "typeShort": "uint", "bits": "256", "displayName": "&thinsp;<span class=\"punctuation\">_</span>&thinsp;goal Amount", "template": "elements_input_uint", "value": "20000000000000000000" } ], "payable": false, "type": "constructor" } ]).at('0xADd563073f3178AbFCDbDd3Ec707e5cd0D280f97')


deadline(終了時間)とキャンペーンのステータスを確認します。

[gethコンソール]

1
2
3
4
5
> cf.deadline()
1625372072

> cf.ended()
false


fund関数をトランザクションで呼び出します。

投資家Aと投資家Bからそれぞれ10etherを送金します。

アカウントごとにロックを解除する必要があります。

[gethコンソール]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
> personal.unlockAccount(eth.accounts[1])
Unlock account 0x63f25b9bbd974fdfa07477cb99c60d2073cfe560
Passphrase:
true

> cf.fund.sendTransaction({from:eth.accounts[1], gas:5000000, value:web3.toWei(10, "ether")})
"0x8895b8f141d011453478fdfa1da51e69814cbd36e171faa60796bc8512b2eebb"

> personal.unlockAccount(eth.accounts[2])
Unlock account 0xd5adf1e9fbc1ed869ed4c7372961238fddc760a5
Passphrase:
true

> cf.fund.sendTransaction({from:eth.accounts[2], gas:5000000, value:web3.toWei(10, "ether")})
"0x7326a3446fec2628b87e1c5c18656be47a5bca238326c73834c25b5281f59b00"


投資家Aからの投資額を確認します。

[gethコンソール]

1
2
3
4
5
> cf.investors(0)[0]
"0x63f25b9bbd974fdfa07477cb99c60d2073cfe560"

> web3.fromWei(cf.investors(0)[1], "ether")
10


投資家Bからの投資額を確認します。

[gethコンソール]

1
2
3
4
5
> cf.investors(1)[0]
"0x0000000000000000000000000000000000000000"

> web3.fromWei(cf.investors(1)[1], "ether")
10

それぞれ10etherずつ投資していることが確認できます。


投資の総額を確認します。

[gethコンソール]

1
2
> web3.fromWei(cf.totalAmount(), "ether")
20


コントラクトの残高を確認します。

[gethコンソール]

1
2
> web3.fromWei(eth.getBalance(cf.address), "ether")
20

目標金額の20etherに達していることが確認できます。


キャンペーンが終了する前のオーナーの残高を確認しておきます。

[gethコンソール]

1
2
> web3.fromWei(eth.getBalance(eth.accounts[0]), "ether")
33734.985904966


あとは、終了時間まで待ってcheckGoalReached関数を呼び出せば、投資された20etherがオーナーのアドレスに振り込まれるはずです。

Mist Walletの画面でコントラクトを表示するとあと何分後かを簡単に確認できます。

[コントラクト確認画面]

キャンペーンの結果確認

キャンペーンが成功したかどうか(目標金額に到達したかどうか)を確認します。

checkGoalReached関数を実行するためには手数料(gas)が必要となりますので、オーナーのアカウントをアンロックしておく必要があります。

[gethコンソール]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
> personal.unlockAccount(eth.accounts[0])
Unlock account 0xec3b01f36b44182746ca109230567c4915512e35
Passphrase:
true

> cf.checkGoalReached.sendTransaction({from:eth.accounts[0], gas:5000000})
"0x674aae7f69819ec1e4112bd4694bb027d35a9c8f60b47eb160bcc5073e149878"

> web3.fromWei(eth.getBalance(eth.accounts[0]), "ether")
33834.985904966

> cf.ended()
true

> cf.status()
"Campaign Succeeded"

Mist Walletでも結果を確認してみます。

[キャンペーン成功結果]

今回はうまくいったようです。

キャンペーンが正常に終了し、オーナーのアドレスが20ether増えて・・・あ、失敗しました😨😨😨

オーナーアカウントでマイニングしていたために、キャンペーンの成功でetherがいくら増えたのか確認できません。

次回は、マイニングアカウントを別にしてもう一度トライしてみます。

(3度目の正直という事で・・・・😅)