First commit
This commit is contained in:
12
.gitignore
vendored
Normal file
12
.gitignore
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
src/js/metacoin-config.js
|
||||
node_modules
|
||||
build
|
||||
.env
|
||||
tmp
|
||||
_old
|
||||
.venv
|
||||
*.mnemonic
|
||||
*_wallet.json
|
||||
*.log
|
||||
_contracts_old
|
24
.vscode/settings.json
vendored
Normal file
24
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"editor.bracketPairColorization.enabled": true,
|
||||
"editor.fontFamily": "'Cascadia Code PL', Consolas, 'Courier New', monospace",
|
||||
"editor.fontLigatures": true,
|
||||
"editor.guides.bracketPairs": true,
|
||||
"editor.linkedEditing": true,
|
||||
"editor.minimap.enabled": false,
|
||||
"editor.tabSize": 2,
|
||||
"editor.useTabStops": true,
|
||||
"editor.formatOnSave": true,
|
||||
"editor.formatOnPaste": true,
|
||||
"files.trimTrailingWhitespace": true,
|
||||
"github.copilot.enable": {
|
||||
"*": true,
|
||||
"markdown": false,
|
||||
"plaintext": false,
|
||||
"scminput": false
|
||||
},
|
||||
"prettier.semi": false,
|
||||
"prettier.singleQuote": true,
|
||||
"prettier.trailingComma": "none",
|
||||
"terminal.integrated.defaultProfile.linux": "JavaScript Debug Terminal",
|
||||
"terminal.integrated.defaultProfile.windows": "JavaScript Debug Terminal"
|
||||
}
|
21
LICENSE
Normal file
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License Copyright (c) 2025 Toni Ramiro <sargatxet@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of
|
||||
charge, to any person obtaining a copy of this software and associated
|
||||
documentation files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to the
|
||||
following conditions:
|
||||
|
||||
The above copyright notice and this permission notice
|
||||
(including the next paragraph) shall be included in all copies or substantial
|
||||
portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
|
||||
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
|
||||
EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
19
contracts/Migrations.sol
Normal file
19
contracts/Migrations.sol
Normal file
@@ -0,0 +1,19 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity >=0.4.22 <0.9.0;
|
||||
|
||||
contract Migrations {
|
||||
address public owner = msg.sender;
|
||||
uint public last_completed_migration;
|
||||
|
||||
modifier restricted() {
|
||||
require(
|
||||
msg.sender == owner,
|
||||
"This function is restricted to the contract's owner"
|
||||
);
|
||||
_;
|
||||
}
|
||||
|
||||
function setCompleted(uint completed) public restricted {
|
||||
last_completed_migration = completed;
|
||||
}
|
||||
}
|
31
contracts/SargaTrxUsdPrice.sol
Normal file
31
contracts/SargaTrxUsdPrice.sol
Normal file
@@ -0,0 +1,31 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.20;
|
||||
|
||||
import {AggregatorV3Interface} from "@chainlink/contracts/src/v0.8/shared/interfaces/AggregatorV3Interface.sol";
|
||||
|
||||
contract SargaTrxUsdPrice {
|
||||
AggregatorV3Interface internal _priceFeed;
|
||||
|
||||
/**
|
||||
* Network: Tron
|
||||
* Aggregator: TRX/USD
|
||||
* Address: TC6o8AakUg4Xz9nHY9qXpJNsgF7CQkwBqF
|
||||
*/
|
||||
constructor(address priceFeedAddress) {
|
||||
_priceFeed = AggregatorV3Interface(priceFeedAddress);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the latest price
|
||||
*/
|
||||
function getLatestPrice() public view returns (int) {
|
||||
(
|
||||
,
|
||||
/* uint80 roundID */ int price /* uint startedAt */ /* uint timeStamp */ /* uint80 answeredInRound */,
|
||||
,
|
||||
,
|
||||
|
||||
) = _priceFeed.latestRoundData();
|
||||
return price;
|
||||
}
|
||||
}
|
8
docker-compose.yml
Normal file
8
docker-compose.yml
Normal file
@@ -0,0 +1,8 @@
|
||||
services:
|
||||
tron:
|
||||
image: tronbox/tre
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- 9090:9090
|
||||
# volumes:
|
||||
# - ./accounts-data:/config # node will load these keys
|
13
lib/logger.js
Normal file
13
lib/logger.js
Normal file
@@ -0,0 +1,13 @@
|
||||
'use strict'
|
||||
|
||||
// Log
|
||||
const logMessage = (source, msg) => {
|
||||
console.log(new Date(), `[${source}]`, msg)
|
||||
}
|
||||
|
||||
// Error
|
||||
const errorMessage = (source, msg) => {
|
||||
console.error(new Date(), `[${source}]`, msg)
|
||||
}
|
||||
|
||||
module.exports = { logMessage, errorMessage }
|
84
lib/tron.js
Normal file
84
lib/tron.js
Normal file
@@ -0,0 +1,84 @@
|
||||
'use strict'
|
||||
|
||||
// Environment
|
||||
require('dotenv').config()
|
||||
|
||||
// Libraries
|
||||
const path = require('path')
|
||||
const fs = require('fs')
|
||||
const { decryptString } = require('./utils')
|
||||
|
||||
// Connect to Tron network
|
||||
const TronWeb = require('tronweb')
|
||||
|
||||
// Set Tron connection
|
||||
const API_URL =
|
||||
process.env.DEBUG === '1'
|
||||
? process.env.TRON_NILE_API
|
||||
: process.env.DEBUG === '2'
|
||||
? process.env.TRON_LOCAL_API
|
||||
: process.env.TRON_MAINNET_API
|
||||
const HttpProvider = TronWeb.providers.HttpProvider
|
||||
const fullNode = new HttpProvider(API_URL)
|
||||
const solidityNode = new HttpProvider(API_URL)
|
||||
const eventServer = API_URL
|
||||
const tronWeb = new TronWeb(fullNode, solidityNode, eventServer)
|
||||
const feeLimit = parseInt(process.env.FEE_LIMIT)
|
||||
|
||||
// Set contract data
|
||||
const contractPath = path.join(
|
||||
__dirname,
|
||||
`../build/contracts/${process.env.CONTRACT_NAME}.json`
|
||||
)
|
||||
const contractData = JSON.parse(fs.readFileSync(contractPath))
|
||||
const contract = tronWeb.contract(
|
||||
contractData.abi,
|
||||
process.env.CONTRACT_ADDRESS
|
||||
)
|
||||
|
||||
// TRX to SUN conversion
|
||||
function trxToSun(trx) {
|
||||
const sun = +(+trx * 1e6).toFixed(0)
|
||||
return sun
|
||||
}
|
||||
|
||||
// SUN to TRX conversion
|
||||
function sunToTrx(sun) {
|
||||
const trx = +(+sun / 1e6).toFixed(6)
|
||||
return trx
|
||||
}
|
||||
|
||||
// Address to base58 conversion
|
||||
function addressToBase58(address) {
|
||||
return tronWeb.address.fromHex(address)
|
||||
}
|
||||
|
||||
// Set default private key
|
||||
function setDefaultPrivateKey(pk) {
|
||||
// Decrypt private key
|
||||
const decPK =
|
||||
pk ||
|
||||
decryptString(process.env.PRIVATE_KEY_MAINNET, process.env.SEED_PASSWORD)
|
||||
// Set private key in TronWeb
|
||||
tronWeb.setPrivateKey(decPK.substring(2))
|
||||
|
||||
return decPK
|
||||
}
|
||||
|
||||
// Get TRX balance
|
||||
const getTrxBalance = async (address) => {
|
||||
const balance = sunToTrx(await tronWeb.trx.getBalance(address))
|
||||
return balance
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
tronWeb,
|
||||
setDefaultPrivateKey,
|
||||
feeLimit,
|
||||
contractData,
|
||||
contract,
|
||||
trxToSun,
|
||||
sunToTrx,
|
||||
addressToBase58,
|
||||
getTrxBalance
|
||||
}
|
73
lib/utils.js
Normal file
73
lib/utils.js
Normal file
@@ -0,0 +1,73 @@
|
||||
'use strict'
|
||||
|
||||
// Libraries
|
||||
const { customAlphabet } = require('nanoid')
|
||||
const StringCrypto = require('string-crypto')
|
||||
const path = require('path')
|
||||
|
||||
// NanoId with custom alphabet
|
||||
const newId = (len) => {
|
||||
const nanoid = customAlphabet(
|
||||
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789',
|
||||
len || 21
|
||||
)
|
||||
return nanoid()
|
||||
}
|
||||
|
||||
// Remove all _id
|
||||
const removeFieldByName = (o, fieldName) => {
|
||||
delete o[fieldName]
|
||||
for (let v of Object.values(o))
|
||||
if (v instanceof Object) removeFieldByName(v, fieldName)
|
||||
}
|
||||
|
||||
// Clean object from unnecesary fields
|
||||
const fieldsToRemove = ['_id']
|
||||
const cleanObject = (o) => {
|
||||
const obj = JSON.parse(JSON.stringify(o))
|
||||
fieldsToRemove.forEach((f) => {
|
||||
removeFieldByName(obj, f)
|
||||
})
|
||||
return obj
|
||||
}
|
||||
|
||||
// Securize sensible data
|
||||
const cryptoOptions = {
|
||||
salt: process.env.CRYPTO_SALT,
|
||||
iterations: parseInt(process.env.CRYPTO_ITERATIONS),
|
||||
digest: process.env.CRYPTO_DIGEST // one of: 'blake2b512' | 'blake2s256' | 'md4' | 'md5' | 'md5-sha1' | 'mdc2' | 'ripemd160' | 'sha1' | 'sha224' | 'sha256' | 'sha3-224' | 'sha3-256' | 'sha3-384' | 'sha3-512' | 'sha384' | 'sha512' | 'sha512-224' | 'sha512-256' | 'sm3' | 'whirlpool';
|
||||
}
|
||||
const stringCypto = new StringCrypto(cryptoOptions)
|
||||
const encryptString = (value, password) => {
|
||||
return stringCypto.encryptString(value, password)
|
||||
}
|
||||
|
||||
const decryptString = (value, password) => {
|
||||
return stringCypto.decryptString(value, password)
|
||||
}
|
||||
|
||||
// Split array into pieces
|
||||
const chunk = (arr, size) =>
|
||||
arr.reduce(
|
||||
(acc, _, i) => (i % size ? acc : [...acc, arr.slice(i, i + size)]),
|
||||
[]
|
||||
)
|
||||
|
||||
// Sleep
|
||||
const sleep = (segundos) => {
|
||||
return new Promise((resolve) => setTimeout(resolve, segundos * 1000))
|
||||
}
|
||||
|
||||
// Get file name
|
||||
const getFileName = (f) => path.basename(f, '.js')
|
||||
|
||||
module.exports = {
|
||||
newId,
|
||||
removeFieldByName,
|
||||
cleanObject,
|
||||
encryptString,
|
||||
decryptString,
|
||||
chunk,
|
||||
sleep,
|
||||
getFileName
|
||||
}
|
7
migrations/1_initial_migration.js
Normal file
7
migrations/1_initial_migration.js
Normal file
@@ -0,0 +1,7 @@
|
||||
require('dotenv').config()
|
||||
|
||||
var Migrations = artifacts.require('./Migrations.sol')
|
||||
|
||||
module.exports = function (deployer) {
|
||||
deployer.deploy(Migrations)
|
||||
}
|
7
migrations/2_deploy_contracts.js
Normal file
7
migrations/2_deploy_contracts.js
Normal file
@@ -0,0 +1,7 @@
|
||||
require('dotenv').config()
|
||||
|
||||
var MyContract = artifacts.require('./SargaTrxUsdPrice.sol')
|
||||
|
||||
module.exports = function (deployer) {
|
||||
deployer.deploy(MyContract)
|
||||
}
|
22
package.json
Normal file
22
package.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "sarga_tron_usd_price",
|
||||
"version": "0.1.0",
|
||||
"description": "Contract to get TRX/USD value",
|
||||
"main": "index.js",
|
||||
"author": "Toni Ramiro <sargatxet@gmail.com>",
|
||||
"license": "MIT",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@chainlink/contracts": "1.4.0",
|
||||
"@noble/secp256k1": "1.7.1",
|
||||
"dotenv": "16.4.7",
|
||||
"solc": "0.8.20",
|
||||
"string-crypto": "2.0.2",
|
||||
"tronbox": "4.1.1",
|
||||
"tronweb": "5.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@openzeppelin/test-helpers": "0.5.16",
|
||||
"chai": "5.2.0"
|
||||
}
|
||||
}
|
1
sample-env
Normal file
1
sample-env
Normal file
@@ -0,0 +1 @@
|
||||
export PRIVATE_KEY_SHASTA=0000000000000000000000000000000000000000000000000000000000000001
|
93
scripts/1_deploy_on_mainnet.js
Normal file
93
scripts/1_deploy_on_mainnet.js
Normal file
@@ -0,0 +1,93 @@
|
||||
require('dotenv').config()
|
||||
|
||||
// Mainnet
|
||||
process.env.DEBUG = '0'
|
||||
|
||||
const fs = require('fs')
|
||||
const { logMessage, errorMessage } = require('../lib/logger')
|
||||
const {
|
||||
tronWeb,
|
||||
setDefaultPrivateKey,
|
||||
contractData,
|
||||
feeLimit,
|
||||
sunToTrx,
|
||||
addressToBase58
|
||||
} = require('../lib/tron')
|
||||
const { sleep } = require('../lib/utils')
|
||||
|
||||
// Binary data of the contract and ABI
|
||||
const bytecode = contractData.bytecode
|
||||
const abi = contractData.abi
|
||||
logMessage('1_deploy_on_mainnet', 'Bytecode and ABI loaded')
|
||||
|
||||
// Get TRX balance
|
||||
const getTrxBalance = async (address) => {
|
||||
const balance = sunToTrx(await tronWeb.trx.getBalance(address))
|
||||
logMessage('1_deploy_on_mainnet', `TRX balance: ${balance} TRX`)
|
||||
return balance
|
||||
}
|
||||
|
||||
async function deployContract() {
|
||||
try {
|
||||
setDefaultPrivateKey()
|
||||
|
||||
logMessage('1_deploy_on_mainnet', 'Deploying contract...')
|
||||
|
||||
// Get TRX balance
|
||||
const address = tronWeb.defaultAddress.base58
|
||||
const balance = await getTrxBalance(address)
|
||||
if (balance < 200) {
|
||||
throw new Error('Insufficient TRX balance to deploy the contract')
|
||||
}
|
||||
|
||||
// Sign transaction
|
||||
const unsignedTxn = await tronWeb.transactionBuilder.createSmartContract({
|
||||
abi,
|
||||
bytecode,
|
||||
feeLimit,
|
||||
callValue: 0, // TRX sent to the contract
|
||||
parameters: [process.env.CHAINLINK_USD_PRICE_FEED]
|
||||
})
|
||||
const signedTxn = await tronWeb.trx.sign(unsignedTxn)
|
||||
logMessage('1_deploy_on_mainnet', 'Transaction signed')
|
||||
|
||||
// Broadcast transaction
|
||||
const tx = await tronWeb.trx.sendRawTransaction(signedTxn)
|
||||
logMessage('1_deploy_on_mainnet', `Transaction ID: ${tx.txid}`)
|
||||
logMessage('1_deploy_on_mainnet', 'Contract deployed')
|
||||
|
||||
// Get contract address
|
||||
let contractAddress = {}
|
||||
do {
|
||||
await sleep(5) // Wait 5 seconds
|
||||
contractAddress = await tronWeb.trx.getTransactionInfo(tx.txid)
|
||||
} while (!contractAddress.contract_address)
|
||||
logMessage(
|
||||
'1_deploy_on_mainnet',
|
||||
`Contract address: ${contractAddress.contract_address}`
|
||||
)
|
||||
|
||||
// Add/Change into .env
|
||||
let envContent = fs.readFileSync('.env', 'utf8')
|
||||
if (/CONTRACT_ADDRESS=/.test(envContent)) {
|
||||
envContent = envContent.replace(
|
||||
/CONTRACT_ADDRESS=.*/,
|
||||
`CONTRACT_ADDRESS=${addressToBase58(contractAddress.contract_address)}`
|
||||
)
|
||||
} else {
|
||||
envContent += `\n\n# Contract address\nCONTRACT_ADDRESS=${addressToBase58(
|
||||
contractAddress.contract_address
|
||||
)}`
|
||||
}
|
||||
fs.writeFileSync('.env', envContent)
|
||||
|
||||
process.exit(0)
|
||||
} catch (error) {
|
||||
errorMessage(
|
||||
'1_deploy_on_mainnet',
|
||||
`ERROR: ${error.message || JSON.stringify(error)}`
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
deployContract()
|
1
test/.git-folder-keeper
Normal file
1
test/.git-folder-keeper
Normal file
@@ -0,0 +1 @@
|
||||
This is a placeholder file to ensure the parent directory in the git repository. Feel free to remove.
|
41
test/SargaTrxUsdPrice.test.js
Normal file
41
test/SargaTrxUsdPrice.test.js
Normal file
@@ -0,0 +1,41 @@
|
||||
// test/SargaTrxUsdPrice.test.js
|
||||
|
||||
require('dotenv').config()
|
||||
|
||||
const TronWeb = require('tronweb')
|
||||
const HttpProvider = TronWeb.providers.HttpProvider
|
||||
const API_URL = process.env.TRON_API
|
||||
const fullNode = new HttpProvider(API_URL)
|
||||
const solidityNode = new HttpProvider(API_URL)
|
||||
const eventServer = API_URL
|
||||
const tronWeb = new TronWeb(fullNode, solidityNode, eventServer)
|
||||
|
||||
let assert
|
||||
|
||||
const SargaTrxUsdPrice = artifacts.require('SargaTrxUsdPrice')
|
||||
|
||||
contract('SargaTrxUsdPrice', () => {
|
||||
it('get TRX/USD value', async () => {
|
||||
// carga Chai como ESM y extrae assert
|
||||
const chaiModule = await import('chai')
|
||||
assert = chaiModule.assert
|
||||
|
||||
// 1) Load already deployed contract
|
||||
const distributor = await SargaTrxUsdPrice.at(process.env.CONTRACT_ADDRESS)
|
||||
|
||||
// 2) Call the getTrxUsdPrice function
|
||||
const trxUsdPrice = await distributor.getLatestPrice().call()
|
||||
console.log(
|
||||
'TRX/USD price:',
|
||||
parseFloat(trxUsdPrice.toString()) / 10 ** 8,
|
||||
'USD'
|
||||
)
|
||||
|
||||
// 3) Assert the value is greater than 0
|
||||
assert.isAbove(
|
||||
parseFloat(trxUsdPrice),
|
||||
0,
|
||||
'TRX/USD price should be greater than 0'
|
||||
)
|
||||
})
|
||||
})
|
3
tronbox-config.js
Normal file
3
tronbox-config.js
Normal file
@@ -0,0 +1,3 @@
|
||||
module.exports = {
|
||||
|
||||
};
|
44
tronbox-evm-config.js
Normal file
44
tronbox-evm-config.js
Normal file
@@ -0,0 +1,44 @@
|
||||
module.exports = {
|
||||
networks: {
|
||||
bttc: {
|
||||
// Don't put your private key here:
|
||||
privateKey: process.env.PRIVATE_KEY_BTTC,
|
||||
/*
|
||||
Create a .env file (it must be gitignored) containing something like
|
||||
|
||||
export PRIVATE_KEY_BTTC=4E7FEC...656243
|
||||
|
||||
Then, run the migration with:
|
||||
|
||||
source .env && tronbox migrate --network bttc --evm
|
||||
*/
|
||||
fullHost: 'https://rpc.bt.io',
|
||||
// gas: 8500000, // Gas sent with each transaction
|
||||
// gasPrice: '500000000000000', // 500,000 gwei (in wei)
|
||||
network_id: '1'
|
||||
},
|
||||
donau: {
|
||||
privateKey: process.env.PRIVATE_KEY_DONAU,
|
||||
fullHost: 'https://pre-rpc.bt.io',
|
||||
network_id: '2'
|
||||
},
|
||||
development: {
|
||||
privateKey: process.env.PRIVATE_KEY_DEV,
|
||||
fullHost: 'http://127.0.0.1:8545',
|
||||
network_id: '9'
|
||||
}
|
||||
},
|
||||
compilers: {
|
||||
solc: {
|
||||
version: '0.8.7',
|
||||
settings: {
|
||||
// optimizer: {
|
||||
// enabled: true,
|
||||
// runs: 200
|
||||
// },
|
||||
// evmVersion: 'istanbul',
|
||||
// viaIR: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
66
tronbox.js
Normal file
66
tronbox.js
Normal file
@@ -0,0 +1,66 @@
|
||||
const port = process.env.HOST_PORT || 9090
|
||||
|
||||
module.exports = {
|
||||
networks: {
|
||||
mainnet: {
|
||||
// Don't put your private key here:
|
||||
privateKey: process.env.PRIVATE_KEY_MAINNET,
|
||||
/*
|
||||
Create a .env file (it must be gitignored) containing something like
|
||||
|
||||
export PRIVATE_KEY_MAINNET=4E7FEC...656243
|
||||
|
||||
Then, run the migration with:
|
||||
|
||||
source .env && tronbox migrate --network mainnet
|
||||
|
||||
*/
|
||||
userFeePercentage: 100,
|
||||
feeLimit: 1000 * 1e6,
|
||||
fullHost: 'https://api.trongrid.io',
|
||||
network_id: '1'
|
||||
},
|
||||
shasta: {
|
||||
privateKey: process.env.PRIVATE_KEY_SHASTA,
|
||||
userFeePercentage: 50,
|
||||
feeLimit: 1000 * 1e6,
|
||||
fullHost: 'https://api.shasta.trongrid.io',
|
||||
network_id: '2'
|
||||
},
|
||||
nile: {
|
||||
privateKey: process.env.PRIVATE_KEY_NILE,
|
||||
userFeePercentage: 100,
|
||||
feeLimit: 1000 * 1e6,
|
||||
fullHost: 'https://nile.trongrid.io',
|
||||
network_id: '3'
|
||||
},
|
||||
development: {
|
||||
// For tronbox/tre docker image
|
||||
privateKey: '0000000000000000000000000000000000000000000000000000000000000001',
|
||||
userFeePercentage: 0,
|
||||
feeLimit: 1000 * 1e6,
|
||||
fullHost: 'http://127.0.0.1:' + port,
|
||||
network_id: '9'
|
||||
},
|
||||
compilers: {
|
||||
solc: {
|
||||
version: "0.8.20", // Specify a Solidity version >= 0.8.20
|
||||
settings: {
|
||||
optimizer: {
|
||||
enabled: true,
|
||||
runs: 200
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
// solc compiler optimize
|
||||
solc: {
|
||||
optimizer: {
|
||||
enabled: true,
|
||||
runs: 200
|
||||
},
|
||||
evmVersion: 'istanbul',
|
||||
viaIR: true,
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user