前に作成した記事で述べた通り,Ethereumのスマートコントラクトにはスマートコントラクトを作る権限も与えられています.
そこで,スマートコントラクトを作成する機能を持ったスマートコントラクトを紹介します.
コード
ここを参考に,一部変更しています.
URL: https://ethereum.stackexchange.com/questions/1415/solidity-create-contract-from-contract
solidityのバージョンは利用しているものに合わせてください.
Factory.sol
pragma solidity ^0.4.6;
contract Factory {
bytes32[] public Names;
address[] public newContracts;
function createContract(bytes32 name){
address newContract = new Contract(name);
newContracts.push(newContract);
}
function getName(uint i) returns (bytes32){
Contract con = Contract(newContracts[i]);
Names.push(con.Name());
return con.Name();
}
function getAddress(uint i) returns (address){
return newContracts[i];
}
}
contract Contract {
bytes32 public Name;
function Contract(bytes32 name){
Name = name;
}
}
解説
スマートコントラクトからスマートコントラクトを作成するためにすることは,2つです.
- 作成するスマートコントラクト(今回の場合はContract)を持つこと.
- スマートコントラクトを実体化すること.
new Contract(name)を行うことで,Contract型のスマートコントラクトを新たに生成します.
この時点で生成されたスマートコントラクトには自動でアドレスが割り振られるため,それをnewContractで受け取っています.
Ropstenに挙げた場合,図のようにEtherscanから確認できます.
作成元のコントラクトから作成後のコントラクトを追跡することができます.
このあたりはTokenの追跡にも似てますね.
下が上記の「スマートコントラクトを作成する機能を持ったスマートコントラクト」で,上がこのスマートコントラクトで作成されたスマートコントラクトになります.
Toがアドレスではなく,Contract Creationになっていますね.
機能一覧
createContract(bytes32 name)
引数に指定したnameパラメータを持つコントラクトを作成する.
getName(uint i)
指定したインデックス(生成順)のコントラクトが持つ名前を返す.
getAddress(uint i)
指定したインデックス(生成順)のコントラクトのアドレスを返す.
truffleでの利用例
$ truffle console
以上のコマンドでコンソールに入ってから,以下のコマンドでcreateContract()を実行できます.
この場合は,「Test」というNameパラメータを持ったスマートコントラクトが作成されます.
上で示した図はこの結果です.
truffle(development)> Factory.deployed().then(function(contractInstance){contractInstance.createContract('Test').then(function(v){console.log(v)})})
あとがき
数行でスマートコントラクトを作成する機能を持ったスマートコントラクトを作成することができました.
とても可能性がある機能だと思うので,どんどん使っていきたいですね.
truffleを使ったスマートコントラクトのデプロイや検証といった工程も今後書きたいと思います.