使用Solidity编写智能合约并部署到以太坊网络。例如,使用Truffle或Hardhat进行部署。
示例:
pragma solidity ^0.6.6;
contract SimpleStorage {
uint256 public storedData;
function set(uint256 x) public {
storedData = x;
}
function get() public view returns (uint256) {
return storedData;
}
}
ABI(应用二进制接口)描述了合约的可用方法和数据结构。部署后会生成ABI和合约地址。
// 使用Metamask的provider
if (window.ethereum) {
window.web3 = new Web3(window.ethereum);
try {
// 请求用户授权
window.ethereum.enable();
} catch (error) {
console.error("用户拒绝了授权");
}
} else if (window.web3) {
window.web3 = new Web3(window.web3.currentProvider);
} else {
console.log("请安装Metamask");
}
const contractABI = [/* ABI JSON */];
const contractAddress = '0xYourContractAddress';
const simpleStorage = new web3.eth.Contract(contractABI, contractAddress);
simpleStorage.methods.get().call()
.then(result => {
console.log('Stored data:', result);
})
.catch(error => {
console.error(error);
});
const account = '0xYourAccountAddress';
simpleStorage.methods.set(42).send({ from: account })
.on('receipt', receipt => {
console.log('Transaction receipt:', receipt);
})
.on('error', error => {
console.error(error);
});
一个简单的完整项目可能包含以下文件和目录结构:
my-dapp/
├── contracts/
│ └── SimpleStorage.sol
├── migrations/
│ └── 2_deploy_contracts.js
├── src/
│ ├── App.js
│ └── index.js
├── public/
├── truffle-config.js
└── package.json
智能合约与前端交互是区块链应用开发中的一个重要部分。以下是一些常用的代码段,帮助你实现前端与智能合约的交互。主要使用的是Web3.js库,这是一种与以太坊区块链进行交互的JavaScript库。
首先,确保你已经安装了Web3.js库。如果还没有安装,可以使用npm进行安装:
npm install web3
在前端代码中,你需要初始化Web3对象,并连接到以太坊节点(可以是本地节点、Infura节点或其他服务节点)。
// 导入Web3
const Web3 = require('web3');
// 创建Web3实例,连接到本地节点或Infura
const web3 = new Web3(new Web3.providers.HttpProvider('https://mainnet.infura.io/v3/YOUR_INFURA_PROJECT_ID'));
假设你的智能合约ABI存储在一个JSON文件中,并且你已经知道合约地址:
const contractABI = [...] // 你的合约ABI
const contractAddress = '0xYourContractAddress';
const contract = new web3.eth.Contract(contractABI, contractAddress);
例如,假设你的智能合约有一个名为getBalance
的函数:
contract.methods.getBalance().call()
.then(balance => {
console.log('Balance:', balance);
})
.catch(error => {
console.error('Error:', error);
});
假设你的智能合约有一个名为transfer
的函数,需要发送交易以调用此函数:
const account = '0xYourAccountAddress';
const privateKey = 'YourPrivateKey';
const data = contract.methods.transfer('0xRecipientAddress', 100).encodeABI();
web3.eth.getTransactionCount(account, 'pending')
.then(nonce => {
const tx = {
from: account,
to: contractAddress,
gas: 2000000,
data: data,
nonce: nonce
};
web3.eth.accounts.signTransaction(tx, privateKey)
.then(signed => {
web3.eth.sendSignedTransaction(signed.rawTransaction)
.on('receipt', receipt => {
console.log('Transaction receipt:', receipt);
})
.on('error', error => {
console.error('Error:', error);
});
});
});
智能合约事件是前端与智能合约交互的另一重要部分。假设你的智能合约有一个名为NewZombie
的事件:
contract.events.NewZombie()
.on('data', event => {
console.log('New Zombie created:', event.returnValues);
})
.on('error', console.error);
以下是一个完整的示例,展示如何初始化Web3,创建智能合约实例,读取数据,发送交易以及监听事件:
const Web3 = require('web3');
const web3 = new Web3(new Web3.providers.HttpProvider('https://mainnet.infura.io/v3/YOUR_INFURA_PROJECT_ID'));
const contractABI = [...] // 你的合约ABI
const contractAddress = '0xYourContractAddress';
const contract = new web3.eth.Contract(contractABI, contractAddress);
// 读取数据
contract.methods.getBalance().call()
.then(balance => {
console.log('Balance:', balance);
})
.catch(error => {
console.error('Error:', error);
});
// 发送交易
const account = '0xYourAccountAddress';
const privateKey = 'YourPrivateKey';
const data = contract.methods.transfer('0xRecipientAddress', 100).encodeABI();
web3.eth.getTransactionCount(account, 'pending')
.then(nonce => {
const tx = {
from: account,
to: contractAddress,
gas: 2000000,
data: data,
nonce: nonce
};
web3.eth.accounts.signTransaction(tx, privateKey)
.then(signed => {
web3.eth.sendSignedTransaction(signed.rawTransaction)
.on('receipt', receipt => {
console.log('Transaction receipt:', receipt);
})
.on('error', error => {
console.error('Error:', error);
});
});
});
// 监听事件
contract.events.NewZombie()
.on('data', event => {
console.log('New Zombie created:', event.returnValues);
})
.on('error', console.error);
通过这些代码段,你可以在前端应用中与智能合约进行交互,实现读取数据、发送交易以及监听事件等功能。
当然可以。以下是一个完整的示例,展示如何开发一个简单的智能合约,部署它,并在前端与之交互。我们将使用Solidity编写智能合约,Truffle进行开发和部署,Ganache作为本地区块链,Web3.js与前端进行交互。
npm install -g truffle
npm install -g ganache-cli
npm install web3
mkdir myDapp
cd myDapp
truffle init
SimpleStorage.sol
: 在
contracts
目录下创建 SimpleStorage.sol
文件,内容如下: pragma solidity ^0.6.0;
contract SimpleStorage {
uint public storedData;
function set(uint x) public {
storedData = x;
}
function get() public view returns (uint) {
return storedData;
}
}
2_deploy_contracts.js
: 在
migrations
目录下创建 2_deploy_contracts.js
文件,内容如下: const SimpleStorage = artifacts.require("SimpleStorage");
module.exports = function(deployer) {
deployer.deploy(SimpleStorage);
};
truffle-config.js
文件中配置开发网络: module.exports = {
networks: {
development: {
host: "127.0.0.1",
port: 8545,
network_id: "*" // 匹配任何网络ID
}
},
compilers: {
solc: {
version: "0.6.0"
}
}
};
ganache-cli
truffle compile
truffle migrate
index.html
: <!DOCTYPE html>
<html>
<head>
<title>Simple Storage DApp</title>
<script src="https://cdn.jsdelivr.net/gh/ethereum/web3.js/dist/web3.min.js"></script>
<script src="app.js"></script>
</head>
<body>
<h1>Simple Storage</h1>
<input type="number" id="value" placeholder="Value to store"/>
<button onclick="set()">Set Value</button>
<button onclick="get()">Get Value</button>
<p id="storedValue"></p>
</body>
</html>
app.js
: // 连接到本地的Ganache网络
var web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:8545"));
// 获取已部署的合约实例
var SimpleStorage;
var simpleStorageInstance;
web3.eth.getAccounts().then(accounts => {
web3.eth.defaultAccount = accounts[0];
});
fetch('SimpleStorage.json')
.then(response => response.json())
.then(data => {
SimpleStorage = new web3.eth.Contract(data.abi, data.networks['5777'].address);
simpleStorageInstance = SimpleStorage;
});
function set() {
var value = document.getElementById("value").value;
simpleStorageInstance.methods.set(value).send({ from: web3.eth.defaultAccount });
}
function get() {
simpleStorageInstance.methods.get().call().then(result => {
document.getElementById("storedValue").innerText = result;
});
}
SimpleStorage.json
复制到前端目录:
编译后Truffle会生成ABI文件
build/contracts/SimpleStorage.json
,将其复制到前端目录。http-server
)启动前端服务器: npm install -g http-server
http-server
http://localhost:8080
),即可与智能合约进行交互。通过以上步骤,你可以创建一个完整的DApp,从智能合约的开发、部署,到前端与智能合约的交互。