mirror of
https://github.com/PatrickAlphaC/dungeons-and-dragons-nft.git
synced 2021-05-29 14:48:35 +03:00
initial setup of truffle project
This commit is contained in:
101
README.md
101
README.md
@@ -1,2 +1,99 @@
|
||||
# dynamic-nft
|
||||
#chainlink #nft
|
||||
# Chainlink Truffle Box
|
||||
|
||||
Implementation of a [Chainlink requesting contract](https://docs.chain.link/docs/create-a-chainlinked-project).
|
||||
|
||||
## Requirements
|
||||
|
||||
- NPM
|
||||
|
||||
## Installation
|
||||
|
||||
Package installation should have occurred for you during the Truffle Box setup. However, if you add dependencies, you'll need to add them to the project by running:
|
||||
|
||||
```bash
|
||||
npm install
|
||||
```
|
||||
|
||||
Or
|
||||
|
||||
```bash
|
||||
yarn install
|
||||
```
|
||||
|
||||
## Test
|
||||
|
||||
```bash
|
||||
npm test
|
||||
```
|
||||
|
||||
## Deploy
|
||||
|
||||
If needed, edit the `truffle-config.js` config file to set the desired network to a different port. It assumes any network is running the RPC port on 8545.
|
||||
|
||||
```bash
|
||||
npm run migrate:dev
|
||||
```
|
||||
|
||||
For deploying to live networks, Truffle will use `truffle-hdwallet-provider` for your mnemonic and an RPC URL. Set your environment variables `$RPC_URL` and `$MNEMONIC` before running:
|
||||
|
||||
```bash
|
||||
npm run migrate:live
|
||||
```
|
||||
|
||||
## Helper Scripts
|
||||
|
||||
There are 3 helper scripts provided with this box in the scripts directory:
|
||||
|
||||
- `fund-contract.js`
|
||||
- `request-data.js`
|
||||
- `read-contract.js`
|
||||
|
||||
They can be used by calling them from `npx truffle exec`, for example:
|
||||
|
||||
```bash
|
||||
npx truffle exec scripts/fund-contract.js --network live
|
||||
```
|
||||
|
||||
The CLI will output something similar to the following:
|
||||
|
||||
```
|
||||
Using network 'live'.
|
||||
|
||||
Funding contract: 0x972DB80842Fdaf6015d80954949dBE0A1700705E
|
||||
0xd81fcf7bfaf8660149041c823e843f0b2409137a1809a0319d26db9ceaeef650
|
||||
Truffle v5.0.25 (core: 5.0.25)
|
||||
Node v10.16.3
|
||||
```
|
||||
|
||||
In the `request-data.js` script, example parameters are provided for you. You can change the oracle address, Job ID, and parameters based on the information available on [our documentation](https://docs.chain.link/docs/testnet-oracles).
|
||||
|
||||
```bash
|
||||
npx truffle exec scripts/request-data.js --network live
|
||||
```
|
||||
|
||||
This creates a request and will return the transaction ID, for example:
|
||||
|
||||
```
|
||||
Using network 'live'.
|
||||
|
||||
Creating request on contract: 0x972DB80842Fdaf6015d80954949dBE0A1700705E
|
||||
0x828f256109f22087b0804a4d1a5c25e8ce9e5ac4bbc777b5715f5f9e5b181a4b
|
||||
Truffle v5.0.25 (core: 5.0.25)
|
||||
Node v10.16.3
|
||||
```
|
||||
|
||||
After creating a request on a live network, you will want to wait 3 blocks for the Chainlink node to respond. Then call the `read-contract.js` script to read the contract's state.
|
||||
|
||||
```bash
|
||||
npx truffle exec scripts/read-contract.js --network live
|
||||
```
|
||||
|
||||
Once the oracle has responded, you will receive a value similar to the one below:
|
||||
|
||||
```
|
||||
Using network 'live'.
|
||||
|
||||
21568
|
||||
Truffle v5.0.25 (core: 5.0.25)
|
||||
Node v10.16.3
|
||||
```
|
||||
|
||||
23
contracts/Migrations.sol
Normal file
23
contracts/Migrations.sol
Normal file
@@ -0,0 +1,23 @@
|
||||
pragma solidity >=0.4.24 <0.7.0;
|
||||
|
||||
contract Migrations {
|
||||
address public owner;
|
||||
uint256 public last_completed_migration;
|
||||
|
||||
modifier restricted() {
|
||||
if (msg.sender == owner) _;
|
||||
}
|
||||
|
||||
constructor() public {
|
||||
owner = msg.sender;
|
||||
}
|
||||
|
||||
function setCompleted(uint256 completed) public restricted {
|
||||
last_completed_migration = completed;
|
||||
}
|
||||
|
||||
function upgrade(address new_address) public restricted {
|
||||
Migrations upgraded = Migrations(new_address);
|
||||
upgraded.setCompleted(last_completed_migration);
|
||||
}
|
||||
}
|
||||
108
contracts/MyContract.sol
Normal file
108
contracts/MyContract.sol
Normal file
@@ -0,0 +1,108 @@
|
||||
pragma solidity 0.6.6;
|
||||
|
||||
import "@chainlink/contracts/src/v0.6/ChainlinkClient.sol";
|
||||
import "@openzeppelin/contracts/access/Ownable.sol";
|
||||
|
||||
/**
|
||||
* @title MyContract is an example contract which requests data from
|
||||
* the Chainlink network
|
||||
* @dev This contract is designed to work on multiple networks, including
|
||||
* local test networks
|
||||
*/
|
||||
contract MyContract is ChainlinkClient, Ownable {
|
||||
uint256 public data;
|
||||
|
||||
/**
|
||||
* @notice Deploy the contract with a specified address for the LINK
|
||||
* and Oracle contract addresses
|
||||
* @dev Sets the storage for the specified addresses
|
||||
* @param _link The address of the LINK token contract
|
||||
*/
|
||||
constructor(address _link) public {
|
||||
if (_link == address(0)) {
|
||||
setPublicChainlinkToken();
|
||||
} else {
|
||||
setChainlinkToken(_link);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Returns the address of the LINK token
|
||||
* @dev This is the public implementation for chainlinkTokenAddress, which is
|
||||
* an internal method of the ChainlinkClient contract
|
||||
*/
|
||||
function getChainlinkToken() public view returns (address) {
|
||||
return chainlinkTokenAddress();
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Creates a request to the specified Oracle contract address
|
||||
* @dev This function ignores the stored Oracle contract address and
|
||||
* will instead send the request to the address specified
|
||||
* @param _oracle The Oracle contract address to send the request to
|
||||
* @param _jobId The bytes32 JobID to be executed
|
||||
* @param _url The URL to fetch data from
|
||||
* @param _path The dot-delimited path to parse of the response
|
||||
* @param _times The number to multiply the result by
|
||||
*/
|
||||
function createRequestTo(
|
||||
address _oracle,
|
||||
bytes32 _jobId,
|
||||
uint256 _payment,
|
||||
string memory _url,
|
||||
string memory _path,
|
||||
int256 _times
|
||||
)
|
||||
public
|
||||
onlyOwner
|
||||
returns (bytes32 requestId)
|
||||
{
|
||||
Chainlink.Request memory req = buildChainlinkRequest(_jobId, address(this), this.fulfill.selector);
|
||||
req.add("url", _url);
|
||||
req.add("path", _path);
|
||||
req.addInt("times", _times);
|
||||
requestId = sendChainlinkRequestTo(_oracle, req, _payment);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice The fulfill method from requests created by this contract
|
||||
* @dev The recordChainlinkFulfillment protects this function from being called
|
||||
* by anyone other than the oracle address that the request was sent to
|
||||
* @param _requestId The ID that was generated for the request
|
||||
* @param _data The answer provided by the oracle
|
||||
*/
|
||||
function fulfill(bytes32 _requestId, uint256 _data)
|
||||
public
|
||||
recordChainlinkFulfillment(_requestId)
|
||||
{
|
||||
data = _data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Allows the owner to withdraw any LINK balance on the contract
|
||||
*/
|
||||
function withdrawLink() public onlyOwner {
|
||||
LinkTokenInterface link = LinkTokenInterface(chainlinkTokenAddress());
|
||||
require(link.transfer(msg.sender, link.balanceOf(address(this))), "Unable to transfer");
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Call this method if no response is received within 5 minutes
|
||||
* @param _requestId The ID that was generated for the request to cancel
|
||||
* @param _payment The payment specified for the request to cancel
|
||||
* @param _callbackFunctionId The bytes4 callback function ID specified for
|
||||
* the request to cancel
|
||||
* @param _expiration The expiration generated for the request to cancel
|
||||
*/
|
||||
function cancelRequest(
|
||||
bytes32 _requestId,
|
||||
uint256 _payment,
|
||||
bytes4 _callbackFunctionId,
|
||||
uint256 _expiration
|
||||
)
|
||||
public
|
||||
onlyOwner
|
||||
{
|
||||
cancelChainlinkRequest(_requestId, _payment, _callbackFunctionId, _expiration);
|
||||
}
|
||||
}
|
||||
5
migrations/1_initial_migration.js
Normal file
5
migrations/1_initial_migration.js
Normal file
@@ -0,0 +1,5 @@
|
||||
const Migrations = artifacts.require('Migrations')
|
||||
|
||||
module.exports = deployer => {
|
||||
deployer.deploy(Migrations)
|
||||
}
|
||||
23
migrations/2_mycontract_migration.js
Normal file
23
migrations/2_mycontract_migration.js
Normal file
@@ -0,0 +1,23 @@
|
||||
const MyContract = artifacts.require('MyContract')
|
||||
const { LinkToken } = require('@chainlink/contracts/truffle/v0.4/LinkToken')
|
||||
const { Oracle } = require('@chainlink/contracts/truffle/v0.6/Oracle')
|
||||
|
||||
module.exports = async (deployer, network, [defaultAccount]) => {
|
||||
// Local (development) networks need their own deployment of the LINK
|
||||
// token and the Oracle contract
|
||||
if (!network.startsWith('live')) {
|
||||
LinkToken.setProvider(deployer.provider)
|
||||
Oracle.setProvider(deployer.provider)
|
||||
try {
|
||||
await deployer.deploy(LinkToken, { from: defaultAccount })
|
||||
await deployer.deploy(Oracle, LinkToken.address, { from: defaultAccount })
|
||||
await deployer.deploy(MyContract, LinkToken.address)
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
}
|
||||
} else {
|
||||
// For live networks, use the 0 address to allow the ChainlinkRegistry
|
||||
// contract automatically retrieve the correct address for you
|
||||
deployer.deploy(MyContract, '0x0000000000000000000000000000000000000000')
|
||||
}
|
||||
}
|
||||
22431
package-lock.json
generated
Normal file
22431
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
31
package.json
Normal file
31
package.json
Normal file
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"name": "@chainlink/box",
|
||||
"version": "0.6.0",
|
||||
"description": "A Chainlink example in a Truffle box",
|
||||
"scripts": {
|
||||
"compile": "npx truffle compile",
|
||||
"console:dev": "npx truffle console --network cldev",
|
||||
"console:live": "npx truffle console --network live",
|
||||
"depcheck": "echo '@chainlink/box' && depcheck --ignore-dirs=build/contracts || true",
|
||||
"solhint": "solhint ./contracts/**/*.sol",
|
||||
"lint": "yarn solhint",
|
||||
"migrate:dev": "npx truffle migrate --reset --network cldev",
|
||||
"migrate:live": "npx truffle migrate --network live",
|
||||
"test": "NODE_ENV=test npx truffle test"
|
||||
},
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@chainlink/contracts": "^0.0.8",
|
||||
"@openzeppelin/contracts": "^3.1.0",
|
||||
"@truffle/hdwallet-provider": "^1.0.40"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@chainlink/belt": "^0.0.1",
|
||||
"@chainlink/test-helpers": "0.0.5",
|
||||
"@openzeppelin/test-helpers": "^0.5.6",
|
||||
"chai": "^4.2.0",
|
||||
"depcheck": "^0.9.1",
|
||||
"solhint": "^2.1.0",
|
||||
"truffle": "^5.1.5"
|
||||
}
|
||||
}
|
||||
24
scripts/fund-contract.js
Normal file
24
scripts/fund-contract.js
Normal file
@@ -0,0 +1,24 @@
|
||||
const MyContract = artifacts.require('MyContract')
|
||||
const LinkTokenInterface = artifacts.require('LinkTokenInterface')
|
||||
|
||||
/*
|
||||
This script is meant to assist with funding the requesting
|
||||
contract with LINK. It will send 1 LINK to the requesting
|
||||
contract for ease-of-use. Any extra LINK present on the contract
|
||||
can be retrieved by calling the withdrawLink() function.
|
||||
*/
|
||||
|
||||
const payment = process.env.TRUFFLE_CL_BOX_PAYMENT || '1000000000000000000'
|
||||
|
||||
module.exports = async callback => {
|
||||
try {
|
||||
const mc = await MyContract.deployed()
|
||||
const tokenAddress = await mc.getChainlinkToken()
|
||||
const token = await LinkTokenInterface.at(tokenAddress)
|
||||
console.log('Funding contract:', mc.address)
|
||||
const tx = await token.transfer(mc.address, payment)
|
||||
callback(tx.tx)
|
||||
} catch (err) {
|
||||
callback(err)
|
||||
}
|
||||
}
|
||||
12
scripts/read-contract.js
Normal file
12
scripts/read-contract.js
Normal file
@@ -0,0 +1,12 @@
|
||||
const MyContract = artifacts.require('MyContract')
|
||||
|
||||
/*
|
||||
This script makes it easy to read the data variable
|
||||
of the requesting contract.
|
||||
*/
|
||||
|
||||
module.exports = async callback => {
|
||||
const mc = await MyContract.deployed()
|
||||
const data = await mc.data.call()
|
||||
callback(data)
|
||||
}
|
||||
33
scripts/request-data.js
Normal file
33
scripts/request-data.js
Normal file
@@ -0,0 +1,33 @@
|
||||
const MyContract = artifacts.require('MyContract')
|
||||
|
||||
/*
|
||||
This script allows for a Chainlink request to be created from
|
||||
the requesting contract. Defaults to the Chainlink oracle address
|
||||
on this page: https://docs.chain.link/docs/testnet-oracles
|
||||
*/
|
||||
|
||||
const oracleAddress =
|
||||
process.env.TRUFFLE_CL_BOX_ORACLE_ADDRESS ||
|
||||
'0xc99B3D447826532722E41bc36e644ba3479E4365'
|
||||
const jobId =
|
||||
process.env.TRUFFLE_CL_BOX_JOB_ID || '3cff0a3524694ff8834bda9cf9c779a1'
|
||||
const payment = process.env.TRUFFLE_CL_BOX_PAYMENT || '1000000000000000000'
|
||||
const url =
|
||||
process.env.TRUFFLE_CL_BOX_URL ||
|
||||
'https://min-api.cryptocompare.com/data/price?fsym=ETH&tsyms=USD'
|
||||
const path = process.env.TRUFFLE_CL_BOX_JSON_PATH || 'USD'
|
||||
const times = process.env.TRUFFLE_CL_BOX_TIMES || '100'
|
||||
|
||||
module.exports = async callback => {
|
||||
const mc = await MyContract.deployed()
|
||||
console.log('Creating request on contract:', mc.address)
|
||||
const tx = await mc.createRequestTo(
|
||||
oracleAddress,
|
||||
web3.utils.toHex(jobId),
|
||||
payment,
|
||||
url,
|
||||
path,
|
||||
times,
|
||||
)
|
||||
callback(tx.tx)
|
||||
}
|
||||
236
test/MyContract_test.js
Normal file
236
test/MyContract_test.js
Normal file
@@ -0,0 +1,236 @@
|
||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||
const { oracle } = require('@chainlink/test-helpers')
|
||||
const { expectRevert, time } = require('@openzeppelin/test-helpers')
|
||||
|
||||
contract('MyContract', accounts => {
|
||||
const { LinkToken } = require('@chainlink/contracts/truffle/v0.4/LinkToken')
|
||||
const { Oracle } = require('@chainlink/contracts/truffle/v0.6/Oracle')
|
||||
const MyContract = artifacts.require('MyContract.sol')
|
||||
|
||||
const defaultAccount = accounts[0]
|
||||
const oracleNode = accounts[1]
|
||||
const stranger = accounts[2]
|
||||
const consumer = accounts[3]
|
||||
|
||||
// These parameters are used to validate the data was received
|
||||
// on the deployed oracle contract. The Job ID only represents
|
||||
// the type of data, but will not work on a public testnet.
|
||||
// For the latest JobIDs, visit our docs here:
|
||||
// https://docs.chain.link/docs/testnet-oracles
|
||||
const jobId = web3.utils.toHex('4c7b7ffb66b344fbaa64995af81e355a')
|
||||
const url =
|
||||
'https://min-api.cryptocompare.com/data/price?fsym=ETH&tsyms=USD,EUR,JPY'
|
||||
const path = 'USD'
|
||||
const times = 100
|
||||
|
||||
// Represents 1 LINK for testnet requests
|
||||
const payment = web3.utils.toWei('1')
|
||||
|
||||
let link, oc, cc
|
||||
|
||||
beforeEach(async () => {
|
||||
link = await LinkToken.new({ from: defaultAccount })
|
||||
oc = await Oracle.new(link.address, { from: defaultAccount })
|
||||
cc = await MyContract.new(link.address, { from: consumer })
|
||||
await oc.setFulfillmentPermission(oracleNode, true, {
|
||||
from: defaultAccount,
|
||||
})
|
||||
})
|
||||
|
||||
describe('#createRequest', () => {
|
||||
context('without LINK', () => {
|
||||
it('reverts', async () => {
|
||||
await expectRevert.unspecified(
|
||||
cc.createRequestTo(oc.address, jobId, payment, url, path, times, {
|
||||
from: consumer,
|
||||
}),
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
context('with LINK', () => {
|
||||
let request
|
||||
|
||||
beforeEach(async () => {
|
||||
await link.transfer(cc.address, web3.utils.toWei('1', 'ether'), {
|
||||
from: defaultAccount,
|
||||
})
|
||||
})
|
||||
|
||||
context('sending a request to a specific oracle contract address', () => {
|
||||
it('triggers a log event in the new Oracle contract', async () => {
|
||||
const tx = await cc.createRequestTo(
|
||||
oc.address,
|
||||
jobId,
|
||||
payment,
|
||||
url,
|
||||
path,
|
||||
times,
|
||||
{ from: consumer },
|
||||
)
|
||||
request = oracle.decodeRunRequest(tx.receipt.rawLogs[3])
|
||||
assert.equal(oc.address, tx.receipt.rawLogs[3].address)
|
||||
assert.equal(
|
||||
request.topic,
|
||||
web3.utils.keccak256(
|
||||
'OracleRequest(bytes32,address,bytes32,uint256,address,bytes4,uint256,uint256,bytes)',
|
||||
),
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('#fulfill', () => {
|
||||
const expected = 50000
|
||||
const response = web3.utils.padLeft(web3.utils.toHex(expected), 64)
|
||||
let request
|
||||
|
||||
beforeEach(async () => {
|
||||
await link.transfer(cc.address, web3.utils.toWei('1', 'ether'), {
|
||||
from: defaultAccount,
|
||||
})
|
||||
const tx = await cc.createRequestTo(
|
||||
oc.address,
|
||||
jobId,
|
||||
payment,
|
||||
url,
|
||||
path,
|
||||
times,
|
||||
{ from: consumer },
|
||||
)
|
||||
request = oracle.decodeRunRequest(tx.receipt.rawLogs[3])
|
||||
await oc.fulfillOracleRequest(
|
||||
...oracle.convertFufillParams(request, response, {
|
||||
from: oracleNode,
|
||||
gas: 500000,
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
it('records the data given to it by the oracle', async () => {
|
||||
const currentPrice = await cc.data.call()
|
||||
assert.equal(
|
||||
web3.utils.padLeft(web3.utils.toHex(currentPrice), 64),
|
||||
web3.utils.padLeft(expected, 64),
|
||||
)
|
||||
})
|
||||
|
||||
context('when my contract does not recognize the request ID', () => {
|
||||
const otherId = web3.utils.toHex('otherId')
|
||||
|
||||
beforeEach(async () => {
|
||||
request.id = otherId
|
||||
})
|
||||
|
||||
it('does not accept the data provided', async () => {
|
||||
await expectRevert.unspecified(
|
||||
oc.fulfillOracleRequest(
|
||||
...oracle.convertFufillParams(request, response, {
|
||||
from: oracleNode,
|
||||
}),
|
||||
),
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
context('when called by anyone other than the oracle contract', () => {
|
||||
it('does not accept the data provided', async () => {
|
||||
await expectRevert.unspecified(
|
||||
cc.fulfill(request.requestId, response, { from: stranger }),
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('#cancelRequest', () => {
|
||||
let request
|
||||
|
||||
beforeEach(async () => {
|
||||
await link.transfer(cc.address, web3.utils.toWei('1', 'ether'), {
|
||||
from: defaultAccount,
|
||||
})
|
||||
const tx = await cc.createRequestTo(
|
||||
oc.address,
|
||||
jobId,
|
||||
payment,
|
||||
url,
|
||||
path,
|
||||
times,
|
||||
{ from: consumer },
|
||||
)
|
||||
request = oracle.decodeRunRequest(tx.receipt.rawLogs[3])
|
||||
})
|
||||
|
||||
context('before the expiration time', () => {
|
||||
it('cannot cancel a request', async () => {
|
||||
await expectRevert(
|
||||
cc.cancelRequest(
|
||||
request.requestId,
|
||||
request.payment,
|
||||
request.callbackFunc,
|
||||
request.expiration,
|
||||
{ from: consumer },
|
||||
),
|
||||
'Request is not expired',
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
context('after the expiration time', () => {
|
||||
beforeEach(async () => {
|
||||
await time.increase(300)
|
||||
})
|
||||
|
||||
context('when called by a non-owner', () => {
|
||||
it('cannot cancel a request', async () => {
|
||||
await expectRevert.unspecified(
|
||||
cc.cancelRequest(
|
||||
request.requestId,
|
||||
request.payment,
|
||||
request.callbackFunc,
|
||||
request.expiration,
|
||||
{ from: stranger },
|
||||
),
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
context('when called by an owner', () => {
|
||||
it('can cancel a request', async () => {
|
||||
await cc.cancelRequest(
|
||||
request.requestId,
|
||||
request.payment,
|
||||
request.callbackFunc,
|
||||
request.expiration,
|
||||
{ from: consumer },
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('#withdrawLink', () => {
|
||||
beforeEach(async () => {
|
||||
await link.transfer(cc.address, web3.utils.toWei('1', 'ether'), {
|
||||
from: defaultAccount,
|
||||
})
|
||||
})
|
||||
|
||||
context('when called by a non-owner', () => {
|
||||
it('cannot withdraw', async () => {
|
||||
await expectRevert.unspecified(cc.withdrawLink({ from: stranger }))
|
||||
})
|
||||
})
|
||||
|
||||
context('when called by the owner', () => {
|
||||
it('transfers LINK to the owner', async () => {
|
||||
const beforeBalance = await link.balanceOf(consumer)
|
||||
assert.equal(beforeBalance, '0')
|
||||
await cc.withdrawLink({ from: consumer })
|
||||
const afterBalance = await link.balanceOf(consumer)
|
||||
assert.equal(afterBalance, web3.utils.toWei('1', 'ether'))
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
28
truffle-config.js
Normal file
28
truffle-config.js
Normal file
@@ -0,0 +1,28 @@
|
||||
const HDWalletProvider = require('@truffle/hdwallet-provider')
|
||||
|
||||
module.exports = {
|
||||
networks: {
|
||||
cldev: {
|
||||
host: '127.0.0.1',
|
||||
port: 8545,
|
||||
network_id: '*',
|
||||
},
|
||||
ganache: {
|
||||
host: '127.0.0.1',
|
||||
port: 7545,
|
||||
network_id: '*',
|
||||
},
|
||||
kovan: {
|
||||
provider: () => {
|
||||
return new HDWalletProvider(process.env.MNEMONIC, process.env.KOVAN_RPC_URL)
|
||||
},
|
||||
network_id: '42',
|
||||
skipDryRun: true,
|
||||
},
|
||||
},
|
||||
compilers: {
|
||||
solc: {
|
||||
version: '0.6.6',
|
||||
},
|
||||
},
|
||||
}
|
||||
Reference in New Issue
Block a user