forked from cerc-io/ipld-eth-server
Upgrade to v5 schema
Now uses: * ipld direct_by_leaf StateDB for basic queries * trie_by_cid StateDB for trie slice and proof queries Also: * vulcanize => cerc refactor * Backend method to close dbs * state tests are in multiple packages, to allow separate ginkgo suites * removes gap-filler module * integration tests and github workflows * run stack-orchestrator for testnet * fix various issues with tests, hardhat server, dockerfile * fix cmd flags / env vars * fix flaky tests and clean up code * remove unused code, scripts * remove outdated docs * update version
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
FROM node:14
|
||||
# Downgrade from 18.16, see https://github.com/NomicFoundation/hardhat/issues/3877
|
||||
FROM node:18.15-slim
|
||||
|
||||
ARG ETH_ADDR
|
||||
ENV ETH_ADDR $ETH_ADDR
|
||||
@@ -11,4 +12,4 @@ RUN npm run compile && ls -lah
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
ENTRYPOINT ["npm", "start"]
|
||||
ENTRYPOINT ["node", "src/index.js"]
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
pragma solidity ^0.8.0;
|
||||
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
|
||||
|
||||
contract GLDToken is ERC20 {
|
||||
constructor() ERC20("Gold", "GLD") {
|
||||
_mint(msg.sender, 1000000000000000000000);
|
||||
|
||||
@@ -16,6 +16,16 @@ task("accounts", "Prints the list of accounts", async () => {
|
||||
/**
|
||||
* @type import('hardhat/config').HardhatUserConfig
|
||||
*/
|
||||
|
||||
const localNetwork = {
|
||||
url: process.env.ETH_ADDR || "http://127.0.0.1:8545",
|
||||
chainId: Number(process.env.ETH_CHAIN_ID) || 99,
|
||||
};
|
||||
|
||||
if (process.env.DEPLOYER_PRIVATE_KEY) {
|
||||
localNetwork["accounts"] = [process.env.DEPLOYER_PRIVATE_KEY];
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
solidity: {
|
||||
version: "0.8.0",
|
||||
@@ -30,14 +40,7 @@ module.exports = {
|
||||
}
|
||||
},
|
||||
networks: {
|
||||
local: {
|
||||
url: 'http://127.0.0.1:8545',
|
||||
chainId: 99
|
||||
},
|
||||
docker: {
|
||||
url: process.env.ETH_ADDR,
|
||||
chainId: 99
|
||||
}
|
||||
}
|
||||
local: localNetwork
|
||||
},
|
||||
defaultNetwork: "local"
|
||||
};
|
||||
|
||||
|
||||
Generated
+2939
-14573
File diff suppressed because it is too large
Load Diff
@@ -4,23 +4,21 @@
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"compile": "npx hardhat compile",
|
||||
"start": "HARDHAT_NETWORK=docker node src/index.js",
|
||||
"start:local": "ETH_ADDR=http://127.0.0.1:8545 npm run start",
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
"start": "node src/index.js"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"description": "",
|
||||
"description": "Solidity contract deployment server for integration testing",
|
||||
"dependencies": {
|
||||
"@openzeppelin/contracts": "^4.0.0",
|
||||
"fastify": "^3.14.2",
|
||||
"hardhat": "^2.2.0",
|
||||
"fastify": "^4.0.0",
|
||||
"hardhat": "^2.14.0",
|
||||
"solidity-create2-deployer": "^0.4.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nomiclabs/hardhat-ethers": "^2.0.2",
|
||||
"@nomiclabs/hardhat-waffle": "^2.0.1",
|
||||
"@nomiclabs/hardhat-ethers": "^2.2.3",
|
||||
"@nomiclabs/hardhat-waffle": "^2.0.4",
|
||||
"chai": "^4.3.4",
|
||||
"ethereum-waffle": "^3.3.0",
|
||||
"ethers": "^5.1.0"
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
const hre = require("hardhat");
|
||||
|
||||
async function main() {
|
||||
// await hre.run('compile');
|
||||
// We get the contract to deploy
|
||||
const GLDToken = await hre.ethers.getContractFactory("GLDToken");
|
||||
const token = await GLDToken.deploy();
|
||||
await token.deployed();
|
||||
console.log("GLDToken deployed to:", token.address, token.deployTransaction.hash);
|
||||
}
|
||||
// We recommend this pattern to be able to use async/await everywhere
|
||||
// and properly handle errors.
|
||||
main()
|
||||
.then(() => process.exit(0))
|
||||
.catch(error => {
|
||||
console.error(error);
|
||||
process.exit(1);
|
||||
});
|
||||
@@ -1,36 +0,0 @@
|
||||
// We require the Hardhat Runtime Environment explicitly here. This is optional
|
||||
// but useful for running the script in a standalone fashion through `node <script>`.
|
||||
//
|
||||
// When running the script with `hardhat run <script>` you'll find the Hardhat
|
||||
// Runtime Environment's members available in the global scope.
|
||||
const hre = require("hardhat");
|
||||
|
||||
async function main() {
|
||||
// Hardhat always runs the compile task when running scripts with its command
|
||||
// line interface.
|
||||
//
|
||||
// If this script is run directly using `node` you may want to call compile
|
||||
// manually to make sure everything is compiled
|
||||
// await hre.run('compile');
|
||||
|
||||
// We get the contract to deploy
|
||||
const Greeter = await hre.ethers.getContractFactory("Greeter");
|
||||
const greeter = await Greeter.deploy("Hello, Hardhat!");
|
||||
|
||||
await greeter.deployed();
|
||||
|
||||
console.log("Greeter deployed to:", greeter.address, "; tx hash: ", greeter.deployTransaction.hash);
|
||||
|
||||
const result = await greeter.setGreeting("Hello 123!");
|
||||
|
||||
console.log("Greeter updated", "; tx hash: ", result.hash, "; block hash: ", result.blockHash);
|
||||
}
|
||||
|
||||
// We recommend this pattern to be able to use async/await everywhere
|
||||
// and properly handle errors.
|
||||
main()
|
||||
.then(() => process.exit(0))
|
||||
.catch(error => {
|
||||
console.error(error);
|
||||
process.exit(1);
|
||||
});
|
||||
+100
-128
@@ -2,8 +2,8 @@ const fastify = require('fastify')({ logger: true });
|
||||
const hre = require("hardhat");
|
||||
|
||||
const {
|
||||
deployContract,
|
||||
isDeployed
|
||||
deployContract,
|
||||
isDeployed
|
||||
} = require("solidity-create2-deployer");
|
||||
|
||||
const { getStorageSlotKey, deployCreate2Factory } = require('./utils');
|
||||
@@ -12,175 +12,147 @@ const CREATE2_FACTORY_ADDRESS = '0x4a27c059FD7E383854Ea7DE6Be9c390a795f6eE3'
|
||||
|
||||
// readiness check
|
||||
fastify.get('/v1/healthz', async (req, reply) => {
|
||||
reply
|
||||
.code(200)
|
||||
.header('Content-Type', 'application/json; charset=utf-8')
|
||||
.send({ success: true })
|
||||
reply
|
||||
.code(200)
|
||||
.header('Content-Type', 'application/json; charset=utf-8')
|
||||
.send({ success: true })
|
||||
});
|
||||
|
||||
fastify.get('/v1/deployContract', async (req, reply) => {
|
||||
const GLDToken = await hre.ethers.getContractFactory("GLDToken");
|
||||
const token = await GLDToken.deploy();
|
||||
await token.deployed();
|
||||
|
||||
return {
|
||||
address: token.address,
|
||||
txHash: token.deployTransaction.hash,
|
||||
blockNumber: token.deployTransaction.blockNumber,
|
||||
blockHash: token.deployTransaction.blockHash,
|
||||
}
|
||||
});
|
||||
|
||||
fastify.get('/v1/destroyContract', async (req, reply) => {
|
||||
const addr = req.query.addr;
|
||||
|
||||
const Token = await hre.ethers.getContractFactory("GLDToken");
|
||||
const token = await Token.attach(addr);
|
||||
|
||||
await token.destroy();
|
||||
const blockNum = await hre.ethers.provider.getBlockNumber()
|
||||
|
||||
return {
|
||||
blockNumber: blockNum,
|
||||
}
|
||||
})
|
||||
|
||||
fastify.get('/v1/sendEth', async (req, reply) => {
|
||||
const to = req.query.to;
|
||||
const value = req.query.value;
|
||||
const to = req.query.to;
|
||||
const value = hre.ethers.utils.parseEther(req.query.value);
|
||||
|
||||
const [owner] = await hre.ethers.getSigners();
|
||||
const tx = await owner.sendTransaction({
|
||||
to,
|
||||
value: hre.ethers.utils.parseEther(value)
|
||||
});
|
||||
await tx.wait(1)
|
||||
const owner = await hre.ethers.getSigner();
|
||||
const tx = await owner.sendTransaction({to, value}).then(tx => tx.wait());
|
||||
|
||||
// console.log(tx);
|
||||
// const coinbaseBalance = await hre.ethers.provider.getBalance(owner.address);
|
||||
// const receiverBalance = await hre.ethers.provider.getBalance(to);
|
||||
// console.log(coinbaseBalance.toString(), receiverBalance.toString());
|
||||
|
||||
return {
|
||||
from: tx.from,
|
||||
to: tx.to,
|
||||
//value: tx.value.toString(),
|
||||
txHash: tx.hash,
|
||||
blockNumber: tx.blockNumber,
|
||||
blockHash: tx.blockHash,
|
||||
}
|
||||
return {
|
||||
from: tx.from,
|
||||
to: tx.to,
|
||||
txHash: tx.hash,
|
||||
blockNumber: tx.blockNumber,
|
||||
blockHash: tx.blockHash,
|
||||
}
|
||||
});
|
||||
|
||||
fastify.get('/v1/deploySLVContract', async (req, reply) => {
|
||||
const SLVToken = await hre.ethers.getContractFactory("SLVToken");
|
||||
const token = await SLVToken.deploy();
|
||||
const receipt = await token.deployTransaction.wait();
|
||||
function contractCreator(name) {
|
||||
return async (req, reply) => {
|
||||
const contract = await hre.ethers.getContractFactory(name);
|
||||
const instance = await contract.deploy();
|
||||
const rct = await instance.deployTransaction.wait();
|
||||
|
||||
return {
|
||||
address: token.address,
|
||||
txHash: token.deployTransaction.hash,
|
||||
blockNumber: receipt.blockNumber,
|
||||
blockHash: receipt.blockHash,
|
||||
address: instance.address,
|
||||
txHash: rct.transactionHash,
|
||||
blockNumber: rct.blockNumber,
|
||||
blockHash: rct.blockHash,
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
fastify.get('/v1/destroySLVContract', async (req, reply) => {
|
||||
function contractDestroyer(name) {
|
||||
return async (req, reply) => {
|
||||
const addr = req.query.addr;
|
||||
|
||||
const SLVToken = await hre.ethers.getContractFactory("SLVToken");
|
||||
const token = SLVToken.attach(addr);
|
||||
|
||||
const tx = await token.destroy();
|
||||
const receipt = await tx.wait();
|
||||
const contract = await hre.ethers.getContractFactory(name);
|
||||
const instance = contract.attach(addr);
|
||||
const rct = await instance.destroy().then(tx => tx.wait());
|
||||
|
||||
return {
|
||||
blockNumber: receipt.blockNumber,
|
||||
blockNumber: rct.blockNumber,
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fastify.get('/v1/deployContract', contractCreator("GLDToken"));
|
||||
fastify.get('/v1/destroyContract', contractDestroyer("GLDToken"));
|
||||
|
||||
fastify.get('/v1/deploySLVContract', contractCreator("SLVToken"));
|
||||
fastify.get('/v1/destroySLVContract', contractDestroyer("SLVToken"));
|
||||
|
||||
fastify.get('/v1/incrementCountA', async (req, reply) => {
|
||||
const addr = req.query.addr;
|
||||
const addr = req.query.addr;
|
||||
|
||||
const SLVToken = await hre.ethers.getContractFactory("SLVToken");
|
||||
const token = await SLVToken.attach(addr);
|
||||
const SLVToken = await hre.ethers.getContractFactory("SLVToken");
|
||||
const token = await SLVToken.attach(addr);
|
||||
|
||||
const tx = await token.incrementCountA();
|
||||
const receipt = await tx.wait();
|
||||
const tx = await token.incrementCountA();
|
||||
const receipt = await tx.wait();
|
||||
|
||||
return {
|
||||
blockNumber: receipt.blockNumber,
|
||||
}
|
||||
return {
|
||||
blockNumber: receipt.blockNumber,
|
||||
}
|
||||
});
|
||||
|
||||
fastify.get('/v1/incrementCountB', async (req, reply) => {
|
||||
const addr = req.query.addr;
|
||||
const addr = req.query.addr;
|
||||
|
||||
const SLVToken = await hre.ethers.getContractFactory("SLVToken");
|
||||
const token = await SLVToken.attach(addr);
|
||||
const SLVToken = await hre.ethers.getContractFactory("SLVToken");
|
||||
const token = await SLVToken.attach(addr);
|
||||
|
||||
const tx = await token.incrementCountB();
|
||||
const receipt = await tx.wait();
|
||||
const tx = await token.incrementCountB();
|
||||
const receipt = await tx.wait();
|
||||
|
||||
return {
|
||||
blockNumber: receipt.blockNumber,
|
||||
}
|
||||
return {
|
||||
blockNumber: receipt.blockNumber,
|
||||
}
|
||||
});
|
||||
|
||||
fastify.get('/v1/getStorageKey', async (req, reply) => {
|
||||
const contract = req.query.contract;
|
||||
const label = req.query.label;
|
||||
const contract = req.query.contract;
|
||||
const label = req.query.label;
|
||||
|
||||
const key = await getStorageSlotKey(contract, label)
|
||||
const key = await getStorageSlotKey(contract, label)
|
||||
|
||||
return {
|
||||
key
|
||||
}
|
||||
return {
|
||||
key
|
||||
}
|
||||
});
|
||||
|
||||
fastify.get('/v1/create2Contract', async (req, reply) => {
|
||||
const contract = req.query.contract;
|
||||
const salt = req.query.salt;
|
||||
const contract = req.query.contract;
|
||||
const salt = req.query.salt;
|
||||
|
||||
const provider = hre.ethers.provider;
|
||||
const signer = await hre.ethers.getSigner();
|
||||
const isFactoryDeployed = await isDeployed(CREATE2_FACTORY_ADDRESS, provider);
|
||||
const provider = hre.ethers.provider;
|
||||
const signer = await hre.ethers.getSigner();
|
||||
const isFactoryDeployed = await isDeployed(CREATE2_FACTORY_ADDRESS, provider);
|
||||
|
||||
if (!isFactoryDeployed) {
|
||||
await deployCreate2Factory(provider, signer)
|
||||
}
|
||||
if (!isFactoryDeployed) {
|
||||
await deployCreate2Factory(provider, signer);
|
||||
}
|
||||
|
||||
const contractFactory = await hre.ethers.getContractFactory(contract);
|
||||
const bytecode = contractFactory.bytecode;
|
||||
const constructorTypes = [];
|
||||
const constructorArgs = [];
|
||||
const contractFactory = await hre.ethers.getContractFactory(contract);
|
||||
const bytecode = contractFactory.bytecode;
|
||||
const constructorTypes = [];
|
||||
const constructorArgs = [];
|
||||
|
||||
const { txHash, address, receipt } = await deployContract({
|
||||
salt,
|
||||
contractBytecode: bytecode,
|
||||
constructorTypes: constructorTypes,
|
||||
constructorArgs: constructorArgs,
|
||||
signer
|
||||
});
|
||||
const createArgs = {
|
||||
salt,
|
||||
contractBytecode: bytecode,
|
||||
constructorTypes: constructorTypes,
|
||||
constructorArgs: constructorArgs,
|
||||
signer
|
||||
};
|
||||
const { txHash, address, receipt } = await deployContract(createArgs);
|
||||
const success = await isDeployed(address, provider);
|
||||
|
||||
const success = await isDeployed(address, provider);
|
||||
|
||||
if (success) {
|
||||
return {
|
||||
address,
|
||||
txHash,
|
||||
blockNumber: receipt.blockNumber,
|
||||
blockHash: receipt.blockHash,
|
||||
}
|
||||
if (success) {
|
||||
return {
|
||||
address,
|
||||
txHash,
|
||||
blockNumber: receipt.blockNumber,
|
||||
blockHash: receipt.blockHash,
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
async function main() {
|
||||
try {
|
||||
await fastify.listen(3000, '0.0.0.0');
|
||||
} catch (err) {
|
||||
fastify.log.error(err);
|
||||
process.exit(1);
|
||||
}
|
||||
try {
|
||||
await fastify.listen({ port: 3000, host: '0.0.0.0' });
|
||||
} catch (err) {
|
||||
fastify.log.error(err);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
process.on('SIGINT', () => fastify.close().then(() => process.exit(1)));
|
||||
|
||||
main();
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
const { artifacts } = require("hardhat")
|
||||
const { utils, BigNumber } = require("ethers")
|
||||
const { deployFactory } = require("solidity-create2-deployer");
|
||||
const { deployFactory, isDeployed } = require("solidity-create2-deployer");
|
||||
|
||||
// Hardcoded account which solidity-create2-deployer uses to deploy its factory
|
||||
const CREATE2_FACTORY_ACCOUNT = '0x2287Fa6efdEc6d8c3E0f4612ce551dEcf89A357A';
|
||||
|
||||
async function getStorageLayout(contractName) {
|
||||
@@ -38,17 +39,17 @@ async function getStorageSlotKey(contractName, variableName) {
|
||||
};
|
||||
|
||||
async function deployCreate2Factory(provider, signer) {
|
||||
// Send eth to account as required to deploy create2 factory contract.
|
||||
// Fund hardcoded account before deploying factory
|
||||
let tx = {
|
||||
to: CREATE2_FACTORY_ACCOUNT,
|
||||
value: utils.parseEther('0.01')
|
||||
}
|
||||
await signer.sendTransaction(tx).then(tx => tx.wait());
|
||||
|
||||
const txResponse = await signer.sendTransaction(tx);
|
||||
await txResponse.wait()
|
||||
|
||||
// Deploy create2 factory contract.
|
||||
await deployFactory(provider)
|
||||
const address = await deployFactory(provider);
|
||||
// solidity-create2-deployer doesn't await the deploy tx
|
||||
while (!await isDeployed(address, provider));
|
||||
return address;
|
||||
}
|
||||
|
||||
module.exports = { getStorageSlotKey, deployCreate2Factory }
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
const { expect } = require("chai");
|
||||
|
||||
describe("Greeter", function() {
|
||||
it("Should return the new greeting once it's changed", async function() {
|
||||
const Greeter = await ethers.getContractFactory("Greeter");
|
||||
const greeter = await Greeter.deploy("Hello, world!");
|
||||
|
||||
await greeter.deployed();
|
||||
expect(await greeter.greet()).to.equal("Hello, world!");
|
||||
|
||||
await greeter.setGreeting("Hola, mundo!");
|
||||
expect(await greeter.greet()).to.equal("Hola, mundo!");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user