使用truffle汇总
truffle主要用来批量编译和部署合约,不再想remix进行手动一个一个部署,可大大提高部署效率。
常用的命令是:
truffle compile,编译成json文件,包含字节码等
truffle migrate/deploy,部署
truffle exec,执行(Execute a JS module within this Truffle environment)
还在学习中,慢慢补充。
写自己的脚本,运行
读取pairCodeHash的值
// contracts // const UniswapV2Router02 = artifacts.require("UniswapV2Router02"); // const UniswapV2Library = artifacts.require("UniswapV2Library"); const Factory = artifacts.require("UniswapV2Factory"); const stripHexPrefix = require('strip-hex-prefix'); const factoryAddressArray = [ "0xcA976B7714f0b48088cCC959C2843Fe752A33855", "0x7e65601AB5A90E2A04Ed4eAa0D91aa34082FdDd3", "0xbBF29Fc64b9D5A90FE3cc75c696C6e542DEcEC35", "0x0A4e77be8aC06F2B4A1f08Ce8006C0B6eC475920", "0x402576A5Ffa4d6A1E6Deb2C3B7082759E3Be686B" ]; let codeArray = []; const woktAddress = ""; module.exports = async function (deployer, network, accounts) { for (var i = 0; i < factoryAddressArray.length; i++) { const factoryInstance = await Factory.at(factoryAddressArray[i]); const hash = await factoryInstance.pairCodeHash(); console.log('hash', factoryAddressArray[i], hash); var replacedContent = "hex'" + stripHexPrefix(hash) + "'" codeArray.push(replacedContent); } console.log(codeArray); // const routerInstance = await UniswapV2Router02.deployed(); // console.log("router address: " + routerInstance.address); };
部署factory
const editJsonFile = require("edit-json-file"); const stripHexPrefix = require('strip-hex-prefix'); const fs = require('fs'); var REGEX = /hex'(.{64,})/g; function replace(path, regex, replacedContent) { // load the html file var fileContent = fs.readFileSync(path, 'utf8'); fileContent = fileContent.replace(regex, replacedContent); // this will overwrite the original html file, change the path for test fs.writeFileSync(path, fileContent); } // contracts const Factory = artifacts.require("UniswapV2Factory"); const ERC20 = artifacts.require("MyERC20") // contracts const UniswapV2Router02 = artifacts.require("UniswapV2Router02"); const UniswapV2Library = artifacts.require("UniswapV2Library"); const SafeMath = artifacts.require("SafeMath"); const StakingRewards = artifacts.require("StakingRewards"); var OutPutFile = "./cList.json" const json = require(OutPutFile) const deadline = 1956981781 // deploy swap factory module.exports = async function(deployer, network, accounts) { for (ts = 0; ts < 5; ts++) { let myMap = new Map(); var erc20Name = new Array() var erc20List = new Array() for (i = 0; i < 4; i++) { const name = "Token" + i await deployer.deploy(ERC20, name, 9000000000000000) const erc20Instance = await ERC20.deployed() erc20List[i] = erc20Instance.address myMap.set(name, erc20Instance.address) } await deployer.deploy(ERC20, "FakeWETH", 9000000000000000) const fakeWETHInstance = await ERC20.deployed() var fakewethAddress = fakeWETHInstance.address myMap.set("FakewethAddress", fakewethAddress) await deployer.deploy(Factory, accounts[0]); const factoryInstance = await Factory.deployed(); const hash = await factoryInstance.pairCodeHash(); var factoryAddress = factoryInstance.address var replacedContent = "hex'" + stripHexPrefix(hash) + "'" replace(`${__dirname}/../contracts/swap/router/libraries/UniswapV2Library.sol`, REGEX, replacedContent); await deployer.deploy(UniswapV2Library); await deployer.link(UniswapV2Library, UniswapV2Router02); await deployer.deploy(SafeMath); await deployer.link(SafeMath, UniswapV2Router02); await deployer.deploy(UniswapV2Router02, factoryAddress, fakewethAddress); const routerInstance = await UniswapV2Router02.deployed(); var routerAddress = routerInstance.address myMap.set("Factory", factoryAddress) myMap.set("Router", routerAddress) var depositAmount = 4000000000000000 for (i = 0; i < erc20List.length; i++) { const erc20I = await ERC20.at(erc20List[i]) await erc20I.approve(routerAddress, depositAmount) } await routerInstance.addLiquidity(erc20List[0], erc20List[1], 3000000000000000, 3000000000000000, 0, 0, accounts[0], deadline) await routerInstance.addLiquidity(erc20List[2], erc20List[3], 3000000000000000, 3000000000000000, 0, 0, accounts[0], deadline) var lp1 = await routerInstance.pairFor(erc20List[0], erc20List[1]) var lp2 = await routerInstance.pairFor(erc20List[2], erc20List[3]) myMap.set("Lp1", lp1) myMap.set("Lp2", lp2) await routerInstance.swapExactTokensForTokens(1000000000000000, 0, [erc20List[0], erc20List[1]], accounts[0], deadline) await routerInstance.swapExactTokensForTokens(1000000000000000, 0, [erc20List[2], erc20List[3]], accounts[0], deadline) // deploy lp1 mining await deployer.deploy(StakingRewards, accounts[0], erc20List[0], lp1, 63072000); var stakingRewardInstance = await StakingRewards.deployed(); myMap.set("StakingRewards1", stakingRewardInstance.address); var erc20I = await ERC20.at(lp1) var balance = await erc20I.balanceOf(accounts[0]) await erc20I.approve(stakingRewardInstance.address, balance) await stakingRewardInstance.stake(balance) erc20I = await ERC20.at(erc20List[0]) balance = await erc20I.balanceOf(accounts[0]) await erc20I.transfer(stakingRewardInstance.address, balance / 2) await stakingRewardInstance.notifyRewardAmount(balance / 2) await stakingRewardInstance.getReward() // deploy lp2 mining await deployer.deploy(StakingRewards, accounts[0], erc20List[2], lp2, 63072000); var stakingRewardInstance = await StakingRewards.deployed(); myMap.set("StakingRewards2", stakingRewardInstance.address); var erc20I = await ERC20.at(lp2) var balance = await erc20I.balanceOf(accounts[0]) await erc20I.approve(stakingRewardInstance.address, balance) await stakingRewardInstance.stake(balance) erc20I = await ERC20.at(erc20List[2]) balance = await erc20I.balanceOf(accounts[0]) await erc20I.transfer(stakingRewardInstance.address, balance / 2) await stakingRewardInstance.notifyRewardAmount(balance / 2) await stakingRewardInstance.getReward() json.push(Object.fromEntries(myMap)) fs.writeFile(OutPutFile,JSON.stringify(json),(err)=>{ if (err) console.log("err",err) }) continue console.log("index", ts) } };
部署router
// contracts const UniswapV2Router02 = artifacts.require("UniswapV2Router02"); const UniswapV2Library = artifacts.require("UniswapV2Library"); const SafeMath = artifacts.require("SafeMath"); const factoryAddress = ""; const woktAddress = ""; module.exports = async function (deployer, network, accounts) { if (factoryAddress === "") { throw new Error('factory address is not set'); } await deployer.deploy(UniswapV2Library); await deployer.link(UniswapV2Library, UniswapV2Router02); await deployer.deploy(SafeMath); await deployer.link(SafeMath, UniswapV2Router02); await deployer.deploy(UniswapV2Router02, factoryAddress, woktAddress); const routerInstance = await UniswapV2Router02.deployed(); console.log("router address: " + routerInstance.address); };
如何运行:
truffle exec your_file.js --network testnet
factory合约的方法 pairCodeHash() 里有一个 type(c).creationCode,其实取的是合约的字节码字段(truffle compile后),即bytecode字段。
type(c).name:获得合约的名字 type(c).creationCode:获得创建合约的字节码 type(c).runtimeCode:获得合约运行时的字节码
配置truffle-config.js
/** * Use this file to configure your truffle project. It's seeded with some * common settings for different networks and features like migrations, * compilation and testing. Uncomment the ones you need or modify * them to suit your project as necessary. * * More information about configuration can be found at: * * trufflesuite.com/docs/advanced/configuration * * To deploy via Infura you'll need a wallet provider (like @truffle/hdwallet-provider) * to sign your transactions before they're sent to a remote public node. Infura accounts * are available for free at: infura.io/register. * * You'll also need a mnemonic - the twelve word phrase the wallet uses to generate * public/private key pairs. If you're publishing your code to GitHub make sure you load this * phrase from a file you've .gitignored so it doesn't accidentally become public. * */ const HDWalletProvider = require('@truffle/hdwallet-provider'); require('dotenv').config() const MAINNET_URL = process.env.MAINNET_URL module.exports = { /** * Networks define how you connect to your ethereum client and let you set the * defaults web3 uses to send transactions. If you don't specify one truffle * will spin up a development blockchain for you on port 9545 when you * run `develop` or `test`. You can ask a truffle command to use a specific * network from the command line, e.g * * $ truffle test --network <network-name> */ networks: { // Useful for testing. The `development` name is special - truffle uses it by default // if it's defined here and no other network is specified at the command line. // You should run a client (like ganache-cli, geth or parity) in a separate terminal // tab if you use this network and you must also set the `host`, `port` and `network_id` // options below to some value. // local: { host: "127.0.0.1", // Localhost (default: none) port: 8545, // Standard Ethereum port (default: none) network_id: "8", // Any network (default: none) }, testnet: { //provider: () => new HDWalletProvider("私钥", "https://http-testnet.hecochain.com"), provider: () => new HDWalletProvider("私钥", "https://exchaintestrpc.okex.org"), network_id: 65, gas: 30000000, gasPrice: 1000000000, networkCheckTimeout: 100000000, timeoutBlocks: 2000, deploymentPollingInterval: 80000 }, mainnet: { provider: () => new HDWalletProvider(MNEMONIC, MAINNET_URL, 0, 2), network_id: 66, }, development: { host: "127.0.0.1", // Localhost (default: none) port: 8545, // Standard Ethereum port (default: none) network_id: "*", // Any network (default: none) }, }, // Set default mocha options here, use special reporters etc. mocha: { // timeout: 100000 }, // Configure your compilers compilers: { solc: { version: "^0.6.6", // Fetch exact version from solc-bin (default: truffle's version) settings: { optimizer: { enabled: true, runs: 1500 } } } } };