前面博文中已經有一篇介紹如何使用web3部署智能合約了,可是針對比較複雜的智能合約那種方式就不行了.
實際上這篇文章的原由是由於打算研究雷電網絡,就想在本身的私鏈上部署一個雷電網絡的合約.結果發現竟然不少問題.html
雷電網絡要正常工做必須藉助兩個事先部署在區塊鏈上的合約才能正常工做,具體來講就是registry和endpointregistry.若是去查看雷電網絡的代碼能夠看到這兩個合約地址是事先寫好在代碼中的. 這兩個合約比較複雜,尤爲是registry.sol,依賴複雜.咱們主要來看幾個主要文件之間的依賴關係: Registry.sol<---ChannelManagerContract.sol<-----ChannelManagerLibrary.sol<-------NettingChannelContract.sol<------NettingChannelLibrary.sol 中間名字裏面有Library的,這些文件是library而不是contract,因此在solc編譯的時候是不會編譯進生成的二進制code中,必須先部署library,而後在對其進行link. 好比:Registry.sol<---ChannelManagerContract.sol<-----ChannelManagerLibrary.sol 那麼在生成Registry.sol的code時,裏面不會包含ChannelManagerLibrary.sol的代碼,只會包含ChannelManagerContract.sol.的代碼.這有點相似於前者是動態連接,然後者是靜態連接. 附上remix生成的registry的bin code,裏面包含了一些字符串__localhost/ChannelManagerLibrary.sol:__,這明顯是錯誤的,這其實是須要替換成ChannelManagerLibrary部署後的地址才能正常工做.
6060604052341561000f57600080fd5b6040516020806109ae8339810160405280805160018054600160a060020a03909216600160a060020a0319909216919091179055505061095a806100546000396000f30060606040526004361061005e5763ffffffff60e060020a6000350416630b74b620811461006e578063238bfba2146100d45780636785b5001461010f5780636cb30fee146101225780639d76ea5814610141578063f26c6aed14610154575b341561006957600080fd5b600080fd5b341561007957600080fd5b610081610176565b60405160208082528190810183818151815260200191508051906020019060200280838360005b838110156100c05780820151838201526020016100a8565b505050509050019250505060405180910390f35b34156100df57600080fd5b6100f3600160a060020a03600435166102c8565b604051600160a060020a03909116815260200160405180910390f35b341561011a57600080fd5b610081610350565b341561012d57600080fd5b610081600160a060020a03600435166103b9565b341561014c57600080fd5b6100f3610446565b341561015f57600080fd5b6100f3600160a060020a0360043516602435610455565b61017e6108d5565b6000806101896108d5565b60008060006002805490506002026040518059106101a45750595b9080825280602002602001820160405250935060009450600095505b6002548610156102bd5760028054879081106101d857fe5b6000918252602082200154600160a060020a031693508390636d2381b390604051608001526040518163ffffffff1660e060020a028152600401608060405180830381600087803b151561022b57600080fd5b6102c65a03f1151561023c57600080fd5b505050604051805190602001805190602001805190602001805190505092505091508184868151811061026b57fe5b600160a060020a03909216602092830290910190910152600194909401938084868151811061029657fe5b600160a060020a0390921660209283029091019091015260019586019594909401936101c0565b509195945050505050565b600073__localhost/ChannelManagerLibrary.sol:__638a1c00e28284816040516020015260405160e060020a63ffffffff85160281526004810192909252600160a060020a0316602482015260440160206040518083038186803b151561033057600080fd5b6102c65a03f4151561034157600080fd5b50505060405180519392505050565b6103586108d5565b60028054806020026020016040519081016040528092919081815260200182805480156103ae57602002820191906000526020600020905b8154600160a060020a03168152600190910190602001808311610390575b505050505090505b90565b6103c16108d5565b6003600083600160a060020a0316600160a060020a0316815260200190815260200160002080548060200260200160405190810160405280929190818152602001828054801561043a57602002820191906000526020600020905b8154600160a060020a0316815260019091019060200180831161041c575b50505050509050919050565b600154600160a060020a031690565b60008060008060008060008061046a8a6102c8565b600160a060020a033381166000908152600360205260408082208e84168352912092995097509095508716156104f4576104a3876108b5565b156104ad57600080fd5b7fda8d2f351e0f7c8c368e631ce8ab15973e7582ece0c347d75a5cff49eb899eb7338b604051600160a060020a039283168152911660208201526040908101905180910390a15b73__localhost/ChannelManagerLibrary.sol:__63941583a560008c8c826040516020015260405160e060020a63ffffffff86160281526004810193909352600160a060020a039091166024830152604482015260640160206040518083038186803b151561056357600080fd5b6102c65a03f4151561057457600080fd5b5050506040518051945050600160a060020a038716156106a357505050600160a060020a038085166000908152600560209081526040808320543385168085526004808552838620968e168652958452828520549584528285209085529092529091205460028054929392859190859081106105ec57fe5b906000526020600020900160006101000a815481600160a060020a030219169083600160a060020a0316021790555083868381548110151561062a57fe5b906000526020600020900160006101000a815481600160a060020a030219169083600160a060020a0316021790555083858281548110151561066857fe5b6000918252602090912001805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a039290921691909117905561084d565b60028054600181016106b583826108e7565b506000918252602090912001805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a03861617905585548690600181016106f983826108e7565b506000918252602090912001805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a038616179055845485906001810161073d83826108e7565b9160005260206000209001600086909190916101000a815481600160a060020a030219169083600160a060020a03160217905550506001600280549050036005600086600160a060020a0316600160a060020a031681526020019081526020016000208190555060018680549050036004600033600160a060020a0316600160a060020a0316815260200190815260200160002060008c600160a060020a0316600160a060020a03168152602001908152602001600020819055506001858054905003600460008c600160a060020a0316600160a060020a03168152602001908152602001600020600033600160a060020a0316600160a060020a03168152602001908152602001600020819055505b7f7bd269696a33040df6c111efd58439c9c77909fcbe90f7511065ac277e175dac84338c8c604051600160a060020a039485168152928416602084015292166040808301919091526060820192909252608001905180910390a1509198975050505050505050565b6000813b818111156108ca57600191506108cf565b600091505b50919050565b60206040519081016040526000815290565b81548183558181151161090b5760008381526020902061090b918101908301610910565b505050565b6103b691905b8082111561092a5760008155600101610916565b50905600a165627a7a7230582000e4924a646ac6cc6f9a6b01f9d4d7d6005bc46a391ce5cd70613d5ad04b015c0029
網上也找了相關的文章看了看,總的來講就是由於若是一個contract使用了library(注意不是import 其餘sol),那麼編譯生成的二進制code是不完整的,必須進行link,目前remix (solidity IDE)是不支持的,因此只能繞過.
好比在部署registry.sol時,具體報錯:node
Error deploying required libraries: Library localhost/ChannelManagerLibrary.sol: not found
這是依賴的最底層,必須先部署. 部署代碼和之前的相似,直接給出完整代碼:
//參考文章:http://web3js.readthedocs.io/en/1.0/web3-eth-contract.html#eth-contract var Web3 = require('web3'); console.log("Web3 Version:",Web3.version); //version 1.0 如下代碼只在此版本測試,更早版本肯定不行 var net = require('net'); var web3 = new Web3(new Web3.providers.IpcProvider("\\\\.\\pipe\\geth.ipc",net)); var eth=web3.eth; deployNettingChannelLibraryContract() function deployNettingChannelLibraryContract(){ var nettingchannellibraryContract =new web3.eth.Contract([{"constant":false,/*忽略*/}]); nettingchannellibraryContract.deploy({ data: '0x60606040523.....', }) .send({ from: "0x1a9ec3b0b807464e6d3398a59d6b0a369bf422fa", gas: 15000000, gasPrice: '30000000000000' }, function(error, transactionHash){ }) .on('error', function(error){ console.log('deploy error') }) .on('transactionHash', function(transactionHash){ }) .on('receipt', function(receipt){ //console.log(receipt.contractAddress) // contains the new contract address }) .on('confirmation', function(confirmationNumber, receipt){ }) .then(function(newContractInstance){ console.log("nettingchannellibraryContract",newContractInstance.options.address) // instance with the new contract address deployChannelManagerLibrary(newContractInstance.options.address) }); }
後面的deployChannelManagerLibrary調用就是說部署NettingChannelLibraryContract成功之後,再去部署上一層的ChannelManagerLibraryweb
部署ChannelManagerLibrary的關鍵是要知道NettingChannelLibraryContract在區塊鏈上的地址 因此必需要先對其二進制code進行替換處理.
var data='0x606060405234156105b...73__localhost/NettingChannelLibrary.sol:__63d...29' data=data.replace(/__localhost\/NettingChannelLibrary.sol:__/g,nettingChannelLibraryAddress.replace("0x","")) channelManagerLibraryContract.deploy({ data:data, })
而後才能進行部署,不然會說code中的__localhost/NettingChannelLibrary.sol不是hex編碼的字符串網絡
完整的代碼,爲了湊字數...,因爲部署registry的思路是一致的,就直接放到一塊兒了.ide
function deployChannelManagerLibrary(nettingChannelLibraryAddress) { var data='0x606060....29' data=data.replace(/__localhost\/NettingChannelLibrary.sol:__/g,nettingChannelLibraryAddress.replace("0x","")) //console.log("after replace data:",data) var channelManagerLibraryContract =new web3.eth.Contract([{"constant":false,/*忽略*/}]); channelManagerLibraryContract.deploy({ data:data, }) .send({ from: "0x1a9ec3b0b807464e6d3398a59d6b0a369bf422fa", gas: 15000000, gasPrice: '30000000000000' }, function(error, transactionHash){ }) .on('error', function(error){ console.log('deploy channelManagerLibraryContract error') }) .then(function(newContractInstance){ console.log("channelManagerLibraryContract",newContractInstance.options.address) // instance with the new contract address deployRegistry(newContractInstance.options.address) }); } function deployRegistry(channelManagerLibraryAddress) { var data='0x6060604....29' data=data.replace(/__localhost\/ChannelManagerLibrary.sol:__/g,channelManagerLibraryAddress.replace("0x","")) //console.log("after replace data:",data) var registryContract =new web3.eth.Contract([{"constant":true,/*忽略*/}]); registryContract.deploy({ data:data, }) .send({ from: "0x1a9ec3b0b807464e6d3398a59d6b0a369bf422fa", gas: 15000000, gasPrice: '30000000000000' }, function(error, transactionHash){ }) .on('error', function(error){ console.log('deploy registryContract error') }) .then(function(newContractInstance){ console.log("registryContract",newContractInstance.options.address) // instance with the new contract address }); }
直接部署,和3.1 部署NettingChannelLibrary.sol中介紹一致,再也不贅述.區塊鏈
node deployregistry.js
Web3 Version: 1.0.0-beta.26 endPointRegistryContract: 0x7eA46670E6A75180e355F9b8fb7501d9618b6D7E nettingchannellibraryContract 0xCeFE92604e376C99568eb951106c8ADCE9D184eF channelManagerLibraryContract 0x15659CeC0602e76EC8e8d5325c2D7a0b4f63f86d registryContract 0x46c9D962c6D5CDc69cF2A7617432eDe2c99a5255
拿到地址,就能夠將源碼中相應地址進行替換,這樣就是一個你本身的雷電網絡了.測試