我們將從檔案瀏覽器開始在左側選單中進行操作。您只需在這裡選擇Owner.sol。
然後,您想將一個選單選項下移到Solidity Compiler。只需單擊藍色的Compile Owner.sol按鈕。
現在將滑鼠移到Deploy&runtransactions選單。只需單擊橙色Deploy按鈕。
請注意,Remix提供了幾個可使用的資金帳戶。每個賬戶有100以太幣資金。)我將使用從0x5B3開始的第一個帳戶來部署合約。
單擊橙色Deploy後,您將看到部署在deployed Contracts下的合約。你也會注意到它有自己的以太坊地址。
我展開了合約,您可以從那裡看到合約中的兩種方法。帶輸入欄位的“ getter” getOwner和“ setter” changeOwner。我單擊getOwner按鈕並看到部署的地址:0x5B38Da6a701c568545dCfcB03FcB875f56beddC4
我想改變合約的所有者。在頂部,我移動到第二個帳戶,以便能夠複製它,然後移回第一個帳戶,即所有者。
現在從0x5B3帳戶執行changeOwner方法,將新帳戶設定為0xAb8帳戶。
現在我再次執行getOwner方法,並正確地將所有者更改為0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2
因此這只是Remix的1分鐘介紹。我建議您自己嘗試一下。嘗試將changeOwner設定為無效地址,或者嘗試使changeOwner不作為所有者,然後看看會發生什麼。
在Ubuntu中使用solc編譯Owner.sol
現在您可能會遇到的一個問題是,Remix中的預設Owner.sol合約使用的編譯器≥0.4.22並且<0.7.0。我的Ubuntu系統上安裝的solc編譯器是0.7.1
# solc --version
solc, the solidity compiler commandline interface
Version: 0.7.1+commit.f4a555be.Linux.g++
對於0.7.1中的合約,語法略有不同。請在下面使用我更改後的Owner.sol。您還可以將Remix中的編譯器版本更改為0.7.1,並也使用此合約。
pragma solidity >=0.4.22 <0.8.0;
contract Owner {
address public owner;
event OwnerSet(address indexed oldOwner, address indexed newOwner);
modifier isOwner() {
require(msg.sender == owner, "Caller is not owner");
_;
}
constructor() {
emit OwnerSet(address(0), owner);
owner = msg.sender;
}
function changeOwner(address newOwner) public isOwner {
emit OwnerSet(owner, newOwner);
owner = newOwner;
}
function getOwner() external view returns (address) {
return owner;
}
}
我希望您按照以下方式編譯Owner.sol合約。
~/dapp# solc --combined-json abi,bin Owner.sol > Owner.json
Warning: SPDX license identifier not provided in source file. Before publishing, consider adding a comment containing "SPDX-License-Identifier: <SPDX-License>" to each source file. Use "SPDX-License-Identifier: UNLICENSED" for non-open-source code. Please see https://spdx.org for more information.
--> Owner.sol
~/dapp# cat Owner.json
{"contracts":{"Owner.sol:Owner":{"abi":"[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"oldOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnerSet\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"changeOwner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]","bin":"608060405234801561001057600080fd5b5060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f342827c97908e5e2f71151c08502a66d44b6f758e3ac2f1de95f02eb95f0a73560405160405180910390a3336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506102f3806100db6000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c8063893d20e8146100465780638da5cb5b1461007a578063a6f9dae1146100ae575b600080fd5b61004e6100f2565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61008261011b565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6100f0600480360360208110156100c457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061013f565b005b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610200576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f43616c6c6572206973206e6f74206f776e65720000000000000000000000000081525060200191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f342827c97908e5e2f71151c08502a66d44b6f758e3ac2f1de95f02eb95f0a73560405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505056fea2646970667358221220ba9a494e8dd99908b8c962ed752cac0bf679199c5c8dad87d13f5f9d9088c39c64736f6c63430007010033"}},"version":"0.7.1+commit.f4a555be.Linux.g++"}
為了方便地讀取這個JSON輸出,我建議安裝“jq”。
apt-get install jq -y
~/dapp# cat Owner.json | jq .
{
"contracts": {
"Owner.sol:Owner": {
"abi": "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"oldOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnerSet\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"changeOwner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]",
"bin": "608060405234801561001057600080fd5b5060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f342827c97908e5e2f71151c08502a66d44b6f758e3ac2f1de95f02eb95f0a73560405160405180910390a3336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506102f3806100db6000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c8063893d20e8146100465780638da5cb5b1461007a578063a6f9dae1146100ae575b600080fd5b61004e6100f2565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61008261011b565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6100f0600480360360208110156100c457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061013f565b005b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610200576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f43616c6c6572206973206e6f74206f776e65720000000000000000000000000081525060200191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f342827c97908e5e2f71151c08502a66d44b6f758e3ac2f1de95f02eb95f0a73560405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505056fea2646970667358221220ba9a494e8dd99908b8c962ed752cac0bf679199c5c8dad87d13f5f9d9088c39c64736f6c63430007010033"
}
},
"version": "0.7.1+commit.f4a555be.Linux.g++"
}
現在,對於下一部分,您將需要一個以太坊Geth節點來安裝智慧合約。
我現在要連線到我的工作節點…
~/geth# ./2020-attach.sh
Welcome to the Geth JavaScript console!
instance: Geth/v1.9.21-stable-0287d548/linux-amd64/go1.15
coinbase: 0x6be8a6cad397746efc5033e27e82477e27c9afec
at block: 3981 (Tue Sep 22 2020 22:44:03 GMT+0100 (BST))
datadir: /root/.ethereum/net2020
modules: admin:1.0 debug:1.0 eth:1.0 ethash:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 txpool:1.0 web3:1.0
> eth.blockNumber
3983
要部署合約,請執行以下操作。
> var ownerContractCompiled = {"contracts":{"Owner.sol:Owner":{"abi":"[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"oldOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnerSet\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"changeOwner\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getOwner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]","bin":"608060405234801561001057600080fd5b5060008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f342827c97908e5e2f71151c08502a66d44b6f758e3ac2f1de95f02eb95f0a73560405160405180910390a3336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506102f3806100db6000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c8063893d20e8146100465780638da5cb5b1461007a578063a6f9dae1146100ae575b600080fd5b61004e6100f2565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61008261011b565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6100f0600480360360208110156100c457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061013f565b005b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610200576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f43616c6c6572206973206e6f74206f776e65720000000000000000000000000081525060200191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f342827c97908e5e2f71151c08502a66d44b6f758e3ac2f1de95f02eb95f0a73560405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505056fea2646970667358221220ba9a494e8dd99908b8c962ed752cac0bf679199c5c8dad87d13f5f9d9088c39c64736f6c63430007010033"}},"version":"0.7.1+commit.f4a555be.Linux.g++"}
> typeof ownerContractCompiled.contracts["Owner.sol:Owner"].abi
"string"
> var ownerContract = eth.contract(JSON.parse(ownerContractCompiled.contracts["Owner.sol:Owner"].abi))
> eth.mining
true <-- make sure you are mining or miner.start(1)
> eth.coinbase
"0x6be8a6cad397746efc5033e27e82477e27c9afec" <-- you will have your own address
> var deployTransactionObject = { from: eth.coinbase, data: "0x" + ownerContractCompiled.contracts["Owner.sol:Owner"].bin, gas: 1000000 }
> personal.unlockAccount(eth.coinbase)
Unlock account 0x6be8a6cad397746efc5033e27e82477e27c9afec
Passphrase:
true
> var ownerContractInstance = ownerContract.new(deployTransactionObject)
請注意,合約已部署,我們的兩種方法都在這裡。
> ownerContractInstance
{
abi: [{
inputs: [],
stateMutability: "nonpayable",
type: "constructor"
}, {
anonymous: false,
inputs: [{...}, {...}],
name: "OwnerSet",
type: "event"
}, {
inputs: [{...}],
name: "changeOwner",
outputs: [],
stateMutability: "nonpayable",
type: "function"
}, {
inputs: [],
name: "getOwner",
outputs: [{...}],
stateMutability: "view",
type: "function"
}, {
inputs: [],
name: "owner",
outputs: [{...}],
stateMutability: "view",
type: "function"
}],
address: "0xb2c455aa1ac281180b4faca7b8896092169ccd55",
transactionHash: "0x38391d46e37e79b7764df2ba31cc32ff45457e2a33a5826b8af15fce9a0e5cf2",
OwnerSet: function(),
allEvents: function(),
changeOwner: function(),
getOwner: function(),
owner: function()
}
區塊鏈中有交易收據。
> eth.getTransactionReceipt(ownerContractInstance.transactionHash);
{
blockHash: "0x94a0e3c9c9d562c34061147e1ef21f9260178693df124ff81cba37f1818fa8a7",
blockNumber: 4061,
contractAddress: "0xb2c455aa1ac281180b4faca7b8896092169ccd55",
cumulativeGasUsed: 287352,
from: "0x6be8a6cad397746efc5033e27e82477e27c9afec",
gasUsed: 287352,
logs: [{
address: "0xb2c455aa1ac281180b4faca7b8896092169ccd55",
blockHash: "0x94a0e3c9c9d562c34061147e1ef21f9260178693df124ff81cba37f1818fa8a7",
blockNumber: 4061,
data: "0x",
logIndex: 0,
removed: false,
topics: ["0x342827c97908e5e2f71151c08502a66d44b6f758e3ac2f1de95f02eb95f0a735", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000"],
transactionHash: "0x38391d46e37e79b7764df2ba31cc32ff45457e2a33a5826b8af15fce9a0e5cf2",
transactionIndex: 0
}],
logsBloom: "0x00000000000000000000000000000000000000000400000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000002000000000000000800000000000000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000004000000000000000000000000000000000",
root: "0xb37e7b1b1e55b358585677fe3cad149e859540f8981c0d9c57d8adc5af536c20",
to: null,
transactionHash: "0x38391d46e37e79b7764df2ba31cc32ff45457e2a33a5826b8af15fce9a0e5cf2",
transactionIndex: 0
}
合約已部署並正常工作。您將不希望一遍又一遍地部署合約以與之整合。這就是您與現有合約進行互動的方式。
> var ownerContractAddress = eth.getTransactionReceipt(ownerContractInstance.transactionHash).contractAddress
> ownerContractAddress
"0xb2c455aa1ac281180b4faca7b8896092169ccd55"
現在你可以在這裡提供合約地址。我們正在使用一個變數,但您也可以提供實際地址。請注意以前使用的“.at”而不是“.new”。這意味著您希望檢索現有合約,而不是建立新合約。
> var ownerContractInstance = ownerContract.at(ownerContractAddress)
任何人都可以檢索合約二進位制檔案。
> var deployedBinary = eth.getCode(ownerContractAddress)
> ("0x" + ownerContractCompiled.contracts["Owner.sol:Owner"].bin.substring(2 + ownerContractCompiled.contracts["Owner.sol:Owner"].bin.length - deployedBinary.length)).localeCompare(deployedBinary);
0 <-- this means the contract is the same as the contract deployed
這就是我們訪問合約方法的方式。
> ownerContractInstance.getOwner()
> ownerContractInstance.setOwner(eth.accounts[1], { from: eth.accounts[0] })
使用React.js或Node.js庫(Web3.js)與您的智慧合約進行互動。
因此,讓我們開始建立一個非常基本的React.js應用程式。我將使用“ create-react-app”工具建立預設應用程式。
% create-react-app mediumtutorialCreating a new React app in /Repos/React/mediumtutorial.*** INSTALL PROCESS ***Success! Created mediumtutorial at /Repos/React/mediumtutorialInside that directory, you can run several commands:yarn start
Starts the development server.yarn build
Bundles the app into static files for production.yarn test
Starts the test runner.yarn eject
Removes this tool and copies build dependencies, configuration files and scripts into the app directory. If you do this, you can’t go back!We suggest that you begin by typing:cd mediumtutorial
yarn startHappy hacking!
按照說明,如果您將目錄更改為“ mediumtutorial”和“ yarn start”,它將開啟您的預設瀏覽器,您應該會看到。
% cd mediumtutorial
mediumtutorial % yarn add web3
該庫可用於Node.js和React.js。您可以像這樣與Geth節點RPC進行互動。
let web3 = new Web3('ws://localhost:8546');