//tips
//smart contract
質問内容が返ってきたので下記に記載。
Question:
04 local contract instances(lottery):
error message:
abort({"code":-32000,"message":"insufficient funds for gas * price + value"}). Build with -s ASSERTIONS=1 for more info.
(Use `node --trace-uncaught ...` to show where the exception was thrown)
Answer:
You will get this error if you are using the wrong mnemonic in your deploy code or if you are using an Infura endpoint that is not the Rinkeby network.
mnemonic ではなく復元用のmnemonic秘密鍵を渡したのが原因だったかもしれないと考えたが、下記のweb3.jsの改善により解決できそう。
Question:
Web3.jsエラー
内容が下記のように更新されてるとのこと。
import Web3 from 'web3';
window.ethereum.request({method:"eth_requestAccounts"});
const web3 = new Web3(window.ethereum);
export default web3;
もしこれでもできなければlotteryの方のdeployが問題。
If you are not getting the address logged to your console it is either because you did not have a successful deployment, or you have pasted the wrong contract address in your lottery.js file.
こちらでconsoleからアカウントを取得できたので、上記は別途調整する。
pickWinerのメソッドの方を先に描いてしまう。
レンダリング箇所に
<h4>Ready to pick a winner?</h4>
<button onClick={this.onClick}>Pick a winner</button>
を追加しonSubmitとは別にonClickを作成。ボタンを押したら実行される関数を作成。onSubmitをフォームを送付したら実行。
onSubmit=async(event)=>{
event.preventDefault();
//Event オブジェクトの preventDefault メソッドを使用することで、
//イベントが発生したときにイベントに対してブラウザで設定されているデフォルトの動作をキャンセルさせることができる
const accounts=await web3.eth.getAccounts();
this.setState({message:'Waiting on transaction success...' });
await lottery.methods.enter().send({
from:accounts[0],
value:web3.utils.toWei(this.state.value,'ether')
});
//transactionが実行され、メタマスクの承認windowが開く
//transaction実行には待機時間があるのでメッセージで知らせる必要がある
this.setState({message:'You have been entered' });
};
onClick= async()=>{
const accounts=await web3.eth.getAccounts();
this.setState({message:'Waiting on transaction success...'})
await lottery.methods.pickWinner().send({
from: accounts[0]
});
this.setState({message:'A winner has been picked'});
}
見直していくとthis.setState({manager,players,balance});はcomponentDidMount(){で外部から取得した変数をstateに落とし込んでいることがわかった。
render()メソッド内では常にstateの情報を監視しているので、stateが変更になるとすぐに更新される仕組み。
この経験を生かし、次のコントラクトを作成していく。
ここからブロックチェーンがクラウドファンディングkickstarterで起こるような資金持ち逃げ問題にどのように対応できるコントラクトを目標とする。
この場合はideaを出して集金した資金の使い道がわかれば、早期にscamを発見できることになる。
どこにお金を送れるかを制御したコントラクトが必要となる。コントラクトは人に対しての出資ではなく、コントラクトプールに対して出資してもらうことにし、実際にアイデアの実行者がspending requestを行うことで、出資金を使用することができる。このrequestに対して、出資者が賛否を投票することで支払いを実行するかどうかが判断される。
先の流れと同様にremixにてベースcontractの生成→ローカルでの組成に移っていく。
Contractの構造は下記になる。
変数:
Manager:アイデアマンのアドレス
Minimum Contribution:最低限の寄付額
Approvers:寄付者のアドレス群
Requests:アイデアマンの支払いリクエスト
関数:
Campain :Minimum Contributionとownerの設定
Contiribute:donateの実行
createRequest:spending request
approveRequest:spending requestへの返事
Finalizerequest:managerがvenderへの支払い
Requestの内容はstructにして、毎回リクエストを作るたびにrequestインスタンスを生成することにする。
pragma solidity ^0.4.17;
contract Campaign{//crowdfunding Campaign
struct Request{//これはインスタンスではなく定義なので、別途インスタンス生成が必要
string description;//送金理由
uint value;//金額
address receipient;//送金先のアドレス
bool complete;//実行可否
}
Request[] public requests;
address public manager;
uint public minimumContribution;//最低限の寄付額
address[] public approvers;
//managerのみ使用可能な制約
modifier restricted(){
require(msg.sender==manager);
_;
}
//contractの初期設定
function Campaign(uint minimum)public {
manager=msg.sender;//contract deployer
minimumContribution=minimum;
}
//donateの実行
function contribute() public payable{
require(msg.value>minimumContribution);//寄付最低額の制約
approvers.push(msg.sender);//approversリストへ追加
}
function createRequest(string description,uint value,address receipient)public restricted{
//requestインスタンス生成とリストへの追加
//生成に必要な引数を取る
Request newRequest=Request({
description:description,
value:value,
receipient:receipient,
complete:false//この段階ではまだ許可されていないので
});
requests.push(newRequest);
}
}