重构:重构和简化区块链和合同代码。

- 在BlockChain.ts中删除未使用的变量和方法,并改进类型。
- 在ERC20Reactor.ts中简化并改进ERC20合同初始化。
- 添加新的WalletReactor.ts文件以实现钱包功能。
This commit is contained in:
zhl 2023-04-06 19:46:36 +08:00
parent 49960fdfa9
commit c98a1b0b2a
6 changed files with 41997 additions and 263 deletions

5851
src/abis/BEBadge.json Normal file

File diff suppressed because one or more lines are too long

36103
src/abis/BEMultiSigWallet.json Normal file

File diff suppressed because one or more lines are too long

View File

@ -23,20 +23,14 @@ export class BlockChain {
this.confirmQueue = new ConfirmQueue(this.web3)
let key = process.env.CHAIN_MASTER_KEY
this.accountMaster = this.web3.eth.accounts.wallet.add(key)
this.web3.eth.accounts.wallet.add(process.env.CHAIN_MINT_KEY)
this.web3.eth.accounts.wallet.add(process.env.CHAIN_ADMIN_KEY)
this.instanceCacheMap = new Map()
this.erc20Reactor = new ERC20Reactor({
web3: this.web3,
address: process.env.CHAIN_FT_ADDRESS,
lockerAddress: process.env.CHAIN_FTLOCKER_ADDRESS,
ctrlAddress: process.env.CHAIN_FTCONTROLLER_ADDRESS,
})
this.erc721Reactor = new ERC721Reactor({
web3: this.web3,
address: process.env.CHAIN_NFT_ADDRESS,
lockerAddress: process.env.CHAIN_NFTLOCKER_ADDRESS,
ctrlAddress: process.env.CHAIN_NFTCONTROLLER_ADDRESS,
})
}

View File

@ -1,40 +1,19 @@
import { BN } from 'ethereumjs-util'
import Web3 from 'web3'
import { FT_ABI, FT_CONTROLLER_ABI, FT_LOCKER_ABI } from './Contracts'
import { Contract } from 'web3-eth-contract'
import { Account } from 'web3-core'
const abiFt = require('abis/ERC20.json').abi
export class ERC20Reactor {
private web3: Web3
private contract: Contract
private locker: Contract
private account: Account
private lockerAddress: string
private ftCtrl: Contract
private ctrlAddress: string
constructor({
web3,
address,
lockerAddress,
ctrlAddress,
}: {
web3: Web3
address: string
lockerAddress?: string
ctrlAddress?: string
}) {
constructor({ web3, address }: { web3: Web3; address: string }) {
this.web3 = web3
this.account = this.web3.eth.accounts.wallet[0]
this.contract = new this.web3.eth.Contract(FT_ABI, address, { from: this.account.address })
if (lockerAddress) {
this.lockerAddress = lockerAddress
this.locker = new this.web3.eth.Contract(FT_LOCKER_ABI, lockerAddress, { from: this.account.address })
}
if (ctrlAddress) {
this.ctrlAddress = ctrlAddress
this.ftCtrl = new this.web3.eth.Contract(FT_CONTROLLER_ABI, ctrlAddress, { from: this.account.address })
}
this.contract = new this.web3.eth.Contract(abiFt, address, { from: this.account.address })
}
/**
@ -46,7 +25,7 @@ export class ERC20Reactor {
*/
async getBalanceOf({ address, selectedAddress }: { address?: string; selectedAddress: string }): Promise<BN> {
const contract = address
? new this.web3.eth.Contract(FT_ABI, address, { from: this.account.address })
? new this.web3.eth.Contract(abiFt, address, { from: this.account.address })
: this.contract
return new Promise<BN>((resolve, reject) => {
contract.methods.balanceOf(selectedAddress).call({ from: selectedAddress }, (error: Error, result: BN) => {
@ -68,7 +47,7 @@ export class ERC20Reactor {
*/
async getTokenDecimals(address?: string): Promise<string> {
const contract = address
? new this.web3.eth.Contract(FT_ABI, address, { from: this.account.address })
? new this.web3.eth.Contract(abiFt, address, { from: this.account.address })
: this.contract
return new Promise<string>((resolve, reject) => {
contract.methods.decimals().call((error: Error, result: BN | string) => {
@ -90,7 +69,7 @@ export class ERC20Reactor {
*/
async getTokenSymbol(address?: string): Promise<string> {
const contract = address
? new this.web3.eth.Contract(FT_ABI, address, { from: this.account.address })
? new this.web3.eth.Contract(abiFt, address, { from: this.account.address })
: this.contract
return new Promise<string>((resolve, reject) => {
contract.methods.symbol().call((error: Error, result: BN | string) => {
@ -144,119 +123,29 @@ export class ERC20Reactor {
amount: number | string
gas?: number
}) {
const contract = new this.web3.eth.Contract(FT_ABI, address, { from: account || this.account.address })
const contract = new this.web3.eth.Contract(abiFt, address, { from: account || this.account.address })
const amountBN = Web3.utils.toBN(Web3.utils.toWei(amount + ''))
return contract.methods.transfer(to, amountBN).send({
return contract.methods.transferFrom(from, to, amountBN).send({
gas: gas || 1000000,
})
}
async mint({ address, to, amount, account }: { account?: string; address?: string; to: string; amount: string }) {
const contract = address
? new this.web3.eth.Contract(FT_ABI, address, { from: account || this.account.address })
? new this.web3.eth.Contract(abiFt, address, { from: account || this.account.address })
: this.contract
// amount = this.web3.utils.toWei(amount + '')
let amountBN = Web3.utils.toBN(Web3.utils.toWei(amount + ''))
let gas = await contract.methods.mint(to, amountBN).estimateGas({ gas: 1000000 })
return contract.methods.mint(to, amountBN).send({ gas: (gas * 1.1) | 0 })
}
async lock({ address, amount, account }: { account?: string; address?: string; amount: string }) {
address = address || this.contract.options.address
// amount = this.web3.utils.toWei(amount + '')
const contract = address
? new this.web3.eth.Contract(FT_ABI, address, { from: account || this.account.address })
: this.contract
let locker = account
? new this.web3.eth.Contract(FT_LOCKER_ABI, this.lockerAddress, { from: account })
: this.locker
const amountBN = Web3.utils.toBN(Web3.utils.toWei(amount + ''))
await contract.methods.increaseAllowance(locker.options.address, amountBN).send({ gas: 1000000 })
let gas = await locker.methods.lock(address, amountBN).estimateGas({ gas: 1000000 })
return locker.methods.lock(address, amountBN).send({ gas: (gas * 1.1) | 0 })
}
async unLock({ address, to, amount, account }: { account?: string; address?: string; to: string; amount: string }) {
address = address || this.contract.options.address
let locker = account
? new this.web3.eth.Contract(FT_LOCKER_ABI, this.lockerAddress, { from: account })
: this.locker
const contract = address
? new this.web3.eth.Contract(FT_ABI, address, { from: account || this.account.address })
: this.contract
const amountBN = Web3.utils.toBN(Web3.utils.toWei(amount + ''))
let gas = await locker.methods.unlock(address, to, amountBN).estimateGas({ gas: 1000000 })
return locker.methods.unlock(address, to, amountBN).send({ gas: (gas * 1.1) | 0 })
}
async releaseFt({
address,
amount,
account,
serverId,
}: {
account?: string
address?: string
amount: string
serverId: string
}) {
address = address || this.contract.options.address
const contract = address
? new this.web3.eth.Contract(FT_ABI, address, { from: account || this.account.address })
: this.contract
let locker = account
? new this.web3.eth.Contract(FT_LOCKER_ABI, this.lockerAddress, { from: account })
: this.locker
const amountBN = Web3.utils.toBN(Web3.utils.toWei(amount + ''))
await contract.methods.increaseAllowance(locker.options.address, amountBN).send({ gas: 1000000 })
let gas = await locker.methods.release(address, amountBN, serverId).estimateGas({ gas: 1000000 })
return locker.methods.release(address, amountBN, serverId).send({ gas: (gas * 1.1) | 0 })
}
async mintReleaseFt({
address,
amount,
serverId,
account,
}: {
address: string
amount: string
serverId: string
account?: string
}) {
const nftCtrl = account
? new this.web3.eth.Contract(FT_CONTROLLER_ABI, this.ctrlAddress, { from: account || this.account.address })
: this.ftCtrl
const amountBN = Web3.utils.toBN(Web3.utils.toWei(amount + ''))
return nftCtrl.methods.mintAndRelease(address, amountBN, serverId).send({ gas: 1000000 })
}
async getLockedNum({ address, account }: { address?: string; account: string }) {
address = address || this.contract.options.address
return this.locker.methods.lockedNum(address, account).call()
}
async getPastEvents({ address, fromBlock }: { address?: string; fromBlock: number }) {
const contract = address
? new this.web3.eth.Contract(FT_ABI, address, { from: this.account.address })
? new this.web3.eth.Contract(abiFt, address, { from: this.account.address })
: this.contract
return contract.getPastEvents('Transfer', {
fromBlock,
toBlock: fromBlock + 50000,
})
}
async getPastLockEvents({ address, fromBlock }: { address?: string; fromBlock: number }) {
return this.locker.getPastEvents('Lock', {
fromBlock,
toBlock: fromBlock + 50000,
})
}
async getPastUnLockEvents({ address, fromBlock }: { address?: string; fromBlock: number }) {
return this.locker.getPastEvents('UnLock', {
fromBlock,
toBlock: fromBlock + 50000,
})
}
}

View File

@ -2,7 +2,6 @@ import { timeoutFetch } from 'utils/net.util'
import { getFormattedIpfsUrl } from 'utils/wallet.util'
import Web3 from 'web3'
import { Contract } from 'web3-eth-contract'
import { NFT_ABI, NFT_CONTROLLER_ABI, NFT_LOCKER_ABI, PRESALE_ABI } from './Contracts'
import { Account } from 'web3-core'
export const ERC721 = 'ERC721'
@ -10,34 +9,17 @@ export const ERC721_INTERFACE_ID = '0x80ac58cd'
export const ERC721_METADATA_INTERFACE_ID = '0x5b5e139f'
export const ERC721_ENUMERABLE_INTERFACE_ID = '0x780e9d63'
const ablNft = require('abis/BEBadge.json').abi
export class ERC721Reactor {
private web3: Web3
private contract: Contract
private locker: Contract
private account: Account
private lockerAddress: string
private nftCtrl: Contract
private ctrlAddress: string
constructor({
web3,
address,
lockerAddress,
ctrlAddress,
}: {
web3: Web3
address: string
lockerAddress: string
ctrlAddress: string
}) {
constructor({ web3, address }: { web3: Web3; address: string }) {
this.web3 = web3
this.account = this.web3.eth.accounts.wallet[0]
this.contract = new this.web3.eth.Contract(NFT_ABI, address, { from: this.account.address })
this.lockerAddress = lockerAddress
this.locker = new this.web3.eth.Contract(NFT_LOCKER_ABI, lockerAddress, { from: this.account.address })
this.ctrlAddress = ctrlAddress
this.nftCtrl = new this.web3.eth.Contract(NFT_CONTROLLER_ABI, this.ctrlAddress)
this.contract = new this.web3.eth.Contract(ablNft, address, { from: this.account.address })
}
/**
@ -88,7 +70,7 @@ export class ERC721Reactor {
index: number
}): Promise<string> => {
const contract = address
? new this.web3.eth.Contract(NFT_ABI, address, { from: this.account.address })
? new this.web3.eth.Contract(ablNft, address, { from: this.account.address })
: this.contract
return new Promise<string>((resolve, reject) => {
contract.methods.tokenOfOwnerByIndex(selectedAddress, index).call((error: Error, result: string) => {
@ -104,7 +86,7 @@ export class ERC721Reactor {
getBalance = async ({ address, selectedAddress }: { address?: string; selectedAddress: string }): Promise<number> => {
const contract = address
? new this.web3.eth.Contract(NFT_ABI, address, { from: this.account.address })
? new this.web3.eth.Contract(ablNft, address, { from: this.account.address })
: this.contract
return new Promise<number>((resolve, reject) => {
contract.methods.balanceOf(selectedAddress).call((error: Error, result: number) => {
@ -127,7 +109,7 @@ export class ERC721Reactor {
*/
getTokenURI = async ({ address, tokenId }: { address?: string; tokenId: string }): Promise<string> => {
const contract = address
? new this.web3.eth.Contract(NFT_ABI, address, { from: this.account.address })
? new this.web3.eth.Contract(ablNft, address, { from: this.account.address })
: this.contract
const supportsMetadata = await this.contractSupportsMetadataInterface(address)
if (!supportsMetadata) {
@ -153,7 +135,7 @@ export class ERC721Reactor {
*/
getAssetName = async (address?: string): Promise<string> => {
const contract = address
? new this.web3.eth.Contract(NFT_ABI, address, { from: this.account.address })
? new this.web3.eth.Contract(ablNft, address, { from: this.account.address })
: this.contract
return new Promise<string>((resolve, reject) => {
contract.methods.name().call((error: Error, result: string) => {
@ -175,7 +157,7 @@ export class ERC721Reactor {
*/
getAssetSymbol = async (address?: string): Promise<string> => {
const contract = address
? new this.web3.eth.Contract(NFT_ABI, address, { from: this.account.address })
? new this.web3.eth.Contract(ablNft, address, { from: this.account.address })
: this.contract
return new Promise<string>((resolve, reject) => {
contract.methods.symbol().call((error: Error, result: string) => {
@ -198,7 +180,7 @@ export class ERC721Reactor {
*/
async getOwnerOf({ address, tokenId }: { address?: string; tokenId: string }): Promise<string> {
const contract = address
? new this.web3.eth.Contract(NFT_ABI, address, { from: this.account.address })
? new this.web3.eth.Contract(ablNft, address, { from: this.account.address })
: this.contract
return new Promise<string>((resolve, reject) => {
contract.methods.ownerOf(tokenId).call((error: Error, result: string) => {
@ -227,7 +209,7 @@ export class ERC721Reactor {
interfaceId: string
}): Promise<boolean> => {
const contract = address
? new this.web3.eth.Contract(NFT_ABI, address, { from: this.account.address })
? new this.web3.eth.Contract(ablNft, address, { from: this.account.address })
: this.contract
return new Promise<boolean>((resolve, reject) => {
contract.methods.supportsInterface(interfaceId).call((error: Error, result: boolean) => {
@ -327,7 +309,7 @@ export class ERC721Reactor {
gas?: number
}) {
const contract = address
? new this.web3.eth.Contract(NFT_ABI, address, { from: account || this.account.address })
? new this.web3.eth.Contract(ablNft, address, { from: account || this.account.address })
: this.contract
return contract.methods.safeTransferFrom(from, to, tokenId).send({
from,
@ -337,7 +319,7 @@ export class ERC721Reactor {
async mint({ address, to, tokenId, configId }: { address?: string; to: string; tokenId: string; configId: string }) {
const contract = address
? new this.web3.eth.Contract(NFT_ABI, address, { from: this.account.address })
? new this.web3.eth.Contract(ablNft, address, { from: this.account.address })
: this.contract
let gas = await contract.methods.mint(to, tokenId, configId).estimateGas({ gas: 1000000 })
return contract.methods.mint(to, tokenId, configId).send({ gas: (gas * 1.1) | 0 })
@ -357,7 +339,7 @@ export class ERC721Reactor {
configIds: string[]
}) {
const contract = address
? new this.web3.eth.Contract(NFT_ABI, address, { from: account || this.account.address })
? new this.web3.eth.Contract(ablNft, address, { from: account || this.account.address })
: this.contract
// let gas = await contract.methods.batchMint(to, tokenIds, configIds).estimateGas({ gas: 1000000 })
return contract.methods.batchMint(to, tokenIds, configIds).send({ gas: 1000000 })
@ -377,120 +359,19 @@ export class ERC721Reactor {
nftType: string
}) {
const contract = address
? new this.web3.eth.Contract(PRESALE_ABI, address, { from: account || this.account.address })
? new this.web3.eth.Contract(ablNft, address, { from: account || this.account.address })
: this.contract
let gas = await contract.methods.mintBox(to, tokenId, nftType).estimateGas({ gas: 1000000 })
return contract.methods.mintBox(to, tokenId, nftType).send({ gas: 1000000 })
}
async lock({ address, tokenId, account }: { account?: string; address?: string; tokenId: string }) {
address = address || this.contract.options.address
const contract = address
? new this.web3.eth.Contract(NFT_ABI, address, { from: this.account.address })
: this.contract
let locker = account
? new this.web3.eth.Contract(NFT_LOCKER_ABI, this.lockerAddress, { from: account })
: this.locker
await contract.methods.setApprovalForAll(locker.options.address, true).send({ gas: 1000000 })
let gas = await locker.methods.lock(address, tokenId).estimateGas({ gas: 1000000 })
return locker.methods.lock(address, tokenId).send({ gas: (gas * 1.1) | 0 })
}
async batchLock({ address, tokenIds, account }: { account?: string; address?: string; tokenIds: string[] }) {
address = address || this.contract.options.address
const contract = address
? new this.web3.eth.Contract(NFT_ABI, address, { from: account || this.account.address })
: this.contract
let locker = account
? new this.web3.eth.Contract(NFT_LOCKER_ABI, this.lockerAddress, { from: account })
: this.locker
await contract.methods.setApprovalForAll(locker.options.address, true).send({ gas: 1000000 })
// let gas = await locker.methods.batchLock(address, tokenIds).estimateGas({ gas: 1000000 })
return locker.methods.batchLock(address, tokenIds).send({ gas: 1000000 })
}
async releaseNft({
address,
tokenIds,
account,
serverId,
}: {
account?: string
address?: string
tokenIds: string[]
serverId: string
}) {
address = address || this.contract.options.address
const contract = address
? new this.web3.eth.Contract(NFT_ABI, address, { from: account || this.account.address })
: this.contract
let locker = account
? new this.web3.eth.Contract(NFT_LOCKER_ABI, this.lockerAddress, { from: account })
: this.locker
await contract.methods.setApprovalForAll(locker.options.address, true).send({ gas: 1000000 })
return locker.methods.release(address, tokenIds, serverId).send({ gas: 1000000 })
}
async mintReleaseNft({
account,
address,
serverId,
tokenIds,
configIds,
}: {
account?: string
address?: string
serverId: string
tokenIds: string[]
configIds: string[]
}) {
const nftCtrl = account
? new this.web3.eth.Contract(NFT_CONTROLLER_ABI, this.ctrlAddress, { from: account || this.account.address })
: this.nftCtrl
return nftCtrl.methods.mintAndRelease(address, tokenIds, configIds, serverId).send({ gas: 1000000 })
}
async unLock({ address, to, tokenId, account }: { account?: string; address?: string; to: string; tokenId: string }) {
address = address || this.contract.options.address
let locker = account
? new this.web3.eth.Contract(NFT_LOCKER_ABI, this.lockerAddress, { from: account })
: this.locker
let gas = await locker.methods.unlock(address, to, tokenId).estimateGas({ gas: 1000000 })
return locker.methods.unlock(address, to, tokenId).send({ gas: (gas * 1.1) | 0 })
}
async getLockedNum({ address, account }: { address?: string; account: string }) {
address = address || this.contract.options.address
return this.locker.methods.lockedNum(address, account).call()
}
async getLockedNft({ address, account }: { address?: string; account: string }) {
address = address || this.contract.options.address
return this.locker.methods.lockedNft(address, account).call()
}
async getPastEvents({ address, fromBlock }: { address?: string; fromBlock: number }) {
const contract = address
? new this.web3.eth.Contract(NFT_ABI, address, { from: this.account.address })
? new this.web3.eth.Contract(ablNft, address, { from: this.account.address })
: this.contract
return contract.getPastEvents('BatchMint', {
fromBlock,
toBlock: fromBlock + 50000,
})
}
async getPastLockEvents({ address, fromBlock }: { address?: string; fromBlock: number }) {
return this.locker.getPastEvents('Lock', {
fromBlock,
toBlock: fromBlock + 50000,
})
}
async getPastUnLockEvents({ address, fromBlock }: { address?: string; fromBlock: number }) {
return this.locker.getPastEvents('UnLock', {
fromBlock,
toBlock: fromBlock + 50000,
})
}
}

View File

@ -0,0 +1,16 @@
import { Contract } from 'web3-eth-contract'
import Web3 from 'web3'
import { Account } from 'web3-core'
const abi = require('abis/BEMultiSigWallet.json').abi
export class WalletReactor {
private web3: Web3
private contract: Contract
private account: Account
constructor({ web3, address }: { web3: Web3; address: string }) {
this.web3 = web3
this.account = this.web3.eth.accounts.wallet[0]
this.contract = new this.web3.eth.Contract(abi, address, { from: this.account.address })
}
}