Giter Club home page Giter Club logo

chainlink-mix's Introduction

⚠️⚠️⚠️ This repo uses the eth-brownie development toolkit which is no longer maintained by its creators. Therefore this repo is not maintained actively either. we recommend you check out the Chainlink starter kits to find other repos that you can use to get started quickly. We recommend the use of the Hardhat or Foundry starter kits for most use cases.

chainlink-mix

NOTE: The new default is Sepolia. NOTE: This has been recently updated for better compatibility with local blockchains. Check out the scripts to learn more.


Chainlink Brownie logo


Average time to resolve an issue Percentage of issues still open

This is a repo to work with and use Chainlink smart contracts in a python environment. If you're brand new to Chainlink, check out the beginner walk-through in remix to learn the basics.

You can also check out the more advanced Chainlink tutorials there as well.

Prerequisites

Please install or have installed the following:

Installation

  1. Install Brownie, if you haven't already. Here is a simple way to install brownie.
python3 -m pip install --user pipx
python3 -m pipx ensurepath
# restart your terminal
pipx install eth-brownie

Or, if that doesn't work, via pip

pip install eth-brownie
  1. Download the mix and install dependencies.
brownie bake chainlink-mix
cd chainlink-mix
pip install -r requirements.txt

This will open up a new Chainlink project. Or, you can clone from source:

git clone https://github.com/PatrickAlphaC/chainlink-mix
cd chainlink-mix

Testnet Development

If you want to be able to deploy to testnets, do the following.

Set your WEB3_INFURA_PROJECT_ID, and PRIVATE_KEY environment variables.

You can get a WEB3_INFURA_PROJECT_ID by getting a free trial of Infura. At the moment, it does need to be infura with brownie. If you get lost, you can follow this guide to getting a project key. You can find your PRIVATE_KEY from your ethereum wallet like metamask.

You'll also need testnet ETH and LINK. You can get LINK and ETH into your wallet by using the faucets located here. If you're new to this, watch this video.. Look at the sepolia section for those specific testnet faucets.

You can add your environment variables to a .env file. You can use the .env.exmple as a template, just fill in the values and rename it to '.env'. Then, uncomment the line # dotenv: .env in brownie-config.yaml

Here is what your .env should look like:

export WEB3_INFURA_PROJECT_ID=<PROJECT_ID>
export PRIVATE_KEY=<PRIVATE_KEY>

AND THEN RUN source .env TO ACTIVATE THE ENV VARIABLES (You'll need to do this every time you open a new terminal, or learn how to set them easier)

WARNING WARNING WARNING

DO NOT SEND YOUR PRIVATE KEY WITH FUNDS IN IT ONTO GITHUB

Otherwise, you can build, test, and deploy on your local environment.

Local Development

For local testing install ganache-cli

npm install -g ganache-cli

or

yarn add global ganache-cli

All the scripts are designed to work locally or on a testnet. You can add a ganache-cli or ganache UI chain like so:

brownie networks add Ethereum ganache host=http://localhost:8545 chainid=1337

And update the brownie config accordingly. There is a deploy_mocks script that will launch and deploy mock Oracles, VRFCoordinators, Link Tokens, and Price Feeds on a Local Blockchain.

Running Scripts and Deployment

This mix provides a simple template for working with Chainlink Smart Contracts. The easiest way to start is to fork the mainnet chain to a local ganache chain. This will allow you to deploy local smart contracts to interact with the Chainlink Price Feeds.

NOTE: It's highly encouraged that you work with a local chain before testing on a testnet. You'll be a much faster developer!

If Sepolia network is not added to brownie by default, run:

brownie networks add Ethereum sepolia host=https://sepolia.infura.io/v3/$WEB3_INFURA_PROJECT_ID chainid=11155111 explorer=https://sepolia.etherscan.io/

Chainlink Price Feeds

This will deploy a smart contract to Sepolia and then read you the latest price via Chainlink Price Feeds.

brownie run scripts/price_feed_scripts/01_deploy_price_consumer_v3.py --network sepolia
brownie run scripts/price_feed_scripts/02_read_price_feed.py --network sepolia

Or, you can use ENS

brownie run scripts/price_feed_scripts/02_read_price_feed_with_ens.py --network sepolia

Otherwise, you can fork mainnet and use that in a local ganache development environment.

brownie console --network mainnet-fork
>>> price_feeds = PriceFeedConsumer.deploy('0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419', {'from': accounts[0]})
.
.
>>> latest_price = price_feeds.getLatestPrice()
>>> latest_price
59169208540

You can also use ENS to get prices. See the ens price feed script for more information.

Chainlink VRF

This will deploy a smart contract to Sepolia and get a Random number via Chainlink VRF.

If you haven't created and funded a subscription on vrf.chain.link you can do so on the UI, or by running:

brownie run scripts/vrf_scripts/create_subscription.py --network sepolia

Before running the next scripts. Running 01_deploy_vrf will also add your consumer contract to the registry.

brownie run scripts/vrf_scripts/01_deploy_vrf_consumer.py --network sepolia
brownie run scripts/vrf_scripts/02_request_randomness.py --network sepolia
brownie run scripts/vrf_scripts/03_read_random_number.py --network sepolia

Chainlink API Call

This will deploy a smart contract to Sepolia and then make an API call via Chainlink API Call.

brownie run scripts/chainlink_api_scripts/01_deploy_api_consumer.py --network sepolia
brownie run scripts/chainlink_api_scripts/02_request_api.py --network sepolia
brownie run scripts/chainlink_api_scripts/03_read_data.py --network sepolia

Chainlink Automation Deployment

This is just to show you how to deploy the Automation Compatible contracts, you can learn more about registering & using them in the Automate Contracts section of the Chainlink documentation.

brownie run scripts/automation_scripts/01_deploy_automation_counter.py --network sepolia
brownie run scripts/automation_scripts/02_check_upkeep.py --network sepolia

Local Development

For local development, you might want to deploy mocks. You can run the script to deploy mocks. Depending on your setup, it might make sense to not deploy mocks if you're looking to fork a mainnet. It all depends on what you're looking to do though. Right now, the scripts automatically deploy a mock so they can run.

Testing

brownie test

For more information on effective testing with Chainlink, check out Testing Smart Contracts

Tests are really robust here! They work for local development and testnets. There are a few key differences between the testnets and the local networks. We utilize mocks so we can work with fake oracles on our testnets.

There is a test_unnecessary folder, which is a good exercise for learning some of the nitty-gritty of smart contract development. It's overkill, so pytest will skip them intentionally. It also has a test_samples folder, which shows an example Chainlink API call transaction receipt.

To test development / local

brownie test

To test mainnet-fork

This will test the same way as local testing, but you will need a connection to a mainnet blockchain (like with the infura environment variable.)

brownie test --network mainnet-fork

To test a testnet

Sepolia is currently supported. Please check the Chainlink docs for which products are supported on which chains.

brownie test --network sepolia

Adding additional Chains

If the blockchain is EVM Compatible, adding new chains can be accomplished by something like:

brownie networks add Ethereum binance-smart-chain host=https://bsc-dataseed1.binance.org chainid=56

or, for a fork:

brownie networks add development binance-fork cmd=ganache-cli host=http://127.0.0.1 fork=https://bsc-dataseed1.binance.org accounts=10 mnemonic=brownie port=8545

Linting

pip install black
pip install autoflake
autoflake --in-place --remove-unused-variables --remove-all-unused-imports -r .
black .

If you're using vscode and the solidity extension, you can create a folder called .vscode at the root folder of this project, and create a file called settings.json, and add the following content:

{
  "solidity.remappings": [
    "@chainlink/=[YOUR_HOME_DIR]/.brownie/packages/smartcontractkit/[email protected]",
    "@openzeppelin/=[YOUR_HOME_DIR]/.brownie/packages/OpenZeppelin/[email protected]"
  ]
}

This will quiet the linting errors it gives you.

Resources

To get started with Brownie:

Any questions? Join our Discord

License

This project is licensed under the MIT license.

chainlink-mix's People

Contributors

7xaquarius avatar andrejrakic avatar ernes avatar itsmehdi97 avatar luisgc93 avatar milancermak avatar pappas999 avatar patrickalphac avatar rankjay avatar sevamove avatar sznicolas avatar zeuslawyer avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

chainlink-mix's Issues

Missing function implementation at VRFCoordinatorV2Mock contract

Description
I'm using VRFCoordinatorV2Mock in my project.
When I try to compile I get this error:

TypeError: Contract "VRFCoordinatorV2Mock" should be marked as abstract.
 --> contracts/test/VRFCoordinatorV2Mock.sol:9:1:
  |
9 | contract VRFCoordinatorV2Mock is VRFCoordinatorV2Interface {
  | ^ (Relevant source part starts here and spans across multiple lines).
Note: Missing implementation: 
   --> @chainlink/contracts/src/v0.8/interfaces/VRFCoordinatorV2Interface.sol:124:3:
    |
124 |   function pendingRequestExists(uint64 subId) external view returns (bool);

This is because pendingRequestExists has not been implemented on the mock contract.
I would like to contribute a PR that adds the implementation as follows:

  function pendingRequestExists(uint64 subId) external view returns (bool) {
    revert("not implemented");
  }

Is this ok or I'm missing something?

Your Environment
Ubuntu with Brownie v1.19.1
Solc version: 0.8.16

Basic Information
n/a

Steps to Reproduce

  • Copy contracts/test/VRFCoordinatorV2Mock.sol file into contracts/ directory
  • Run brownie compile

Additional Information
n/a

E brownie.exceptions.VirtualMachineError: revert

I am new to the brownie framework but it seems there is fundamental issue that i can not resolve. I am testing with the basic price feed data that comes with the install. I am using using mainnet-fork from alchemy . I am getting below error while testing,

print( pricefeed.getLatestPrice())
E brownie.exceptions.VirtualMachineError: revert

I have tested solc 0.6 and 0.8 versions and same error is reproducible in brownie console as well as python test script with brownie-config.yaml file. Please find the below file.

Appreciate any insight. thanks

pricefeed.sol:

// SPDX-License-Identifier: MIT
pragma solidity ^0.6.6;

import "@chainlink/contracts/src/v0.6/interfaces/AggregatorV3Interface.sol";

contract PriceFeed {

AggregatorV3Interface internal priceFeed;

/**
 * Network: Kovan
 * Aggregator: ETH/USD
 * Address: 0x9326BFA02ADD2366b30bacB125260Af641031331
 */
/**
 * Network: Mainnet
 * Aggregator: ETH/USD
 * Address: 0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419
 */
constructor(address AggregatorAddress) public {
    priceFeed = AggregatorV3Interface(AggregatorAddress);
}

/**
 * Returns the latest price
 */
function getLatestPrice() public view returns (int) {
    (
        uint80 roundID, 
        int price,
        uint startedAt,
        uint timeStamp,
        uint80 answeredInRound
    ) = priceFeed.latestRoundData();
    return price;
}

}

brownie-config.yaml

dependencies:
- smartcontractkit/[email protected]
compiler:
solc:
remappings:
- '@chainlink=smartcontractkit/[email protected]'
networks:
mainnet-fork:
eth_usd_price_feed: '0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419'

test.py

from brownie import PriceFeed, accounts, config, network
from web3 import Web3
def test_get_entrance_fee():
account = accounts[0]
pricefeed = PriceFeed.deploy(
config["networks"][network.show_active()]["eth_usd_price_feed"],
{"from":account})
assert lottery.getLatestPrice() !=0

Cannot find scripts/price_feed_scripts/deploy_price_consumer_v3.py

I am doing Patrick's tutorial from here, after calling brownie run scripts/price_feed_scripts/deploy_price_consumer_v3.py --network kovan I get the following error:

ChainlinkProject is the active project.
  File "c:\users\szabi\appdata\roaming\python\python38\lib\site-packages\brownie\_cli\__main__.py", line 64, in main
    importlib.import_module(f"brownie._cli.{cmd}").main()
  File "c:\users\szabi\appdata\roaming\python\python38\lib\site-packages\brownie\_cli\run.py", line 46, in main
    path, _ = _get_path(args["<filename>"])
  File "c:\users\szabi\appdata\roaming\python\python38\lib\site-packages\brownie\project\scripts.py", line 130, in _get_path
    raise FileNotFoundError(f"Cannot find {path_str}")
FileNotFoundError: Cannot find scripts/price_feed_scripts/deploy_price_consumer_v3.py

I assume the filenames were updated and brownie bakes an old version because I have 01_deploy_price_consumer_v3.py and it requires deploy_price_consumer_v3.py

brownie test is stuck

I just run these command:
brownie bake chainlink-mix, cd chainlink and brownie test
Now test is stuck at this point: tests/test_api_consumer.py ......

test_api_consumer.py not working

I could run the other 3 tests fine. But the test_api_consumer.py just stuck:

Brownie v1.19.3 - Python development framework for Ethereum

============================= test session starts ===================================
platform win32 -- Python 3.8.10, pytest-6.2.5, py-1.11.0, pluggy-1.0.0
rootdir: C:\Users\compt\demos\chainlink-mix
plugins: eth-brownie-1.19.3, hypothesis-6.27.3, forked-1.4.0, xdist-1.34.0, web3-5.31.3
collected 2 items

Launching 'ganache-cli.cmd --chain.vmErrorsOnRPCResponse true --wallet.totalAccounts 10 --hardfork istanbul --miner.blockGasLimit 12000000 --wallet.mnemonic brownie --server.port 8545'...

tests\test_api_consumer.py

ValueError: Gas estimation failed

Hi, I am a new user of brownie. I keep getting this error when I'm running chainlink_api_scripts/02_request_api.py. I wonder what could go wrong. Thank you for your explanation.

ValueError: Gas estimation failed: 'execution reverted'. This transaction will likely revert. If you wish to broadcast, you must set the gas limit manually.

Python3 not showing up in version check

In setting up my environment, when I get to checking to make sure python downloaded properly, I enter python3 --version. I get an error every time- I have uninstalled, reinstalled, making sure it is the right one- used CL, power shell tried in VS

Nothing seems to work to make sure this step is properly installing.

Add `.env` support

For environment variables, use a .env as an alternative. Possibly an improvement for the brownie repo itself.

Withdraw from aave with brownie

So i wanted to try to withdraw the assets that i landed on aave. Ichecked the aave v2 documentetation and it told me to use the withdraw function, i used it as it told me to and everytime this error pops up:
VirtualMachineError: revert: 6

Can someone help me?
P.S. The rest of the code works fine it's the withdrawing that is giving me problems

from brownie import network, config, interface
from scripts.helpful_scripts import get_account
from scripts.get_weth import get_weth
from web3 import Web3

amount = Web3.toWei(0.1, "ether")

def main():
account = get_account()
erc20_token_address = config["networks"][network.show_active()]["weth_token"]
if network.show_active() in ["mainnet-fork"]:
get_weth()
# ABI
# Address
lending_pool = get_lending_pool()
# Approve sending our ERC20 tokens
approve_erc20(amount, lending_pool.address, erc20_token_address, account)
print("Depositing in aave....")
tx_deposit = lending_pool.deposit(
erc20_token_address, amount, account.address, 0, {"from": account}
)
tx_deposit.wait(1)
print("Deposited!")
# ... how much can we borrow?
borrowable_eth, total_debt = get_borrowable_data(lending_pool, account)
print("Let's borrow!")
# DAI in terms of ETH
dai_to_eht_price = get_asset_price(
config["networks"][network.show_active()]["dai_eth_price_feed"]
)
amount_dai_to_borrow = (1 / dai_to_eht_price) * (borrowable_eth * 0.95)
# borrowable eth to -> borrowable dai * 95%
print(f"We are going to borrow {amount_dai_to_borrow} DAI")
# Now we will borrow
dai_address = config["networks"][network.show_active()]["dai_token"]
borrow_tx = lending_pool.borrow(
dai_address,
Web3.toWei(amount_dai_to_borrow, "ether"),
1,
0,
account.address,
{"from": account},
)
borrow_tx.wait(1)
print("You borrowed some DAI!")
get_borrowable_data(lending_pool, account)
print("Repaying DAI borrowed...")
repay_all(Web3.toWei(amount_dai_to_borrow, "ether"), lending_pool, account)
get_borrowable_data(lending_pool, account)
print("Withdrawing lended assets...")
withdraw(erc20_token_address, amount, account, lending_pool)
get_borrowable_data(lending_pool, account)
print("You just deposited, borrowed and repayed with aave, brownie, and chianlink ")

def withdraw(erc20_token_address, amount, account, lending_pool):
approve_erc20(amount, lending_pool.address, erc20_token_address, account)
withdraw_tx = lending_pool.withdraw(
erc20_token_address, amount, account.address, {"from": account}
)
withdraw_tx.wait(1)
print("Withdrawed!")
return withdraw_tx

Add support for Type Hinting

As now, Type hinting is strongly recommended by the whole Python community and is a huge step ahead while debugging, since that information can be used for static analysis.

The cost to add Type Hinting is minimal, requires small knowledge, and makes the code more robust, secure and readable.

Do you think that fits your project goals? If so, I can be a volunteer to this task.

Unable to compile due to Permission Error

I tried to import AggregatorV3Interface and SafeMathChainlink via "@chainlink" syntax in FundMe.sol Contract. I am getting the following error while trying to compile using, "brownie compile" command.
// Get the latest ETH/USD price from chainlink price feed import "@chainlink/contracts/src/v0.6/interfaces/AggregatorV3Interface.sol"; import "@chainlink/contracts/src/v0.6/vendor/SafeMathChainlink.sol";
and the error raised while trying to compile is,
WARNING: Unable to compile smartcontractkit/[email protected] due to a PermissionError - you may still be able to import sources from the package, but will be unable to load the package directly.

Lesson6 raise TypeError(f"{abi['name']} requires no arguments") TypeError: constructor requires no arguments

Hi!

I used to follow this lesson on a Windows 10 environment, but just switched to using Linux (Ubuntu 20.4).
I then proceeded to reinstall each program necessary to follow the lesson (I had been taking notes so I reinstalled them in the order they appeared in the video).

When typing program --version on my terminal, here is what comes back for each of them:
NodeJs version v16.3.1
Python version Python 3.8.10
NPM version 8.3.0
Yarn version 1.22.17
Brownie version 1.17.2
Pip version pip 20.0.2 from /usr/lib/python3/dist-packages/pip (python 3.8)
Pipx version 0.17.0
Ganache CLI v6.12.2 (ganache-core: 2.13.2)

I copied-pasted the folders I had previously, made sure they were similar to the original ones from Patrick's repo. I had previously stopped, on Windows 10, at the pytest section, so I started running my compiler using brownie compile, which didn't work at first, but I made it work after messing with the solc version and the compiler, and then proceeded to try to run the first script I had made through brownie run scripts/deploy.py. The Mocks were deployed properly and I could see the block being created and my ETH spent on my local Ganache window.

But right after comes this error message:

anne@AnneSager:~/Documents/Programming/brownie_fund_me-1$ brownie run scripts/deploy.py
Brownie v1.17.2 - Python development framework for Ethereum

BrownieFundMe1Project is the active project.
/home/anne/.local/pipx/venvs/eth-brownie/lib/python3.8/site-packages/brownie/network/main.py:44: BrownieEnvironmentWarning: Development network has a block height of 13
  warnings.warn(
Attached to local RPC client listening at '127.0.0.1:8545'...

Running 'scripts/deploy.py::main'...
The active network is development
Deploying Mocks...
Transaction sent: 0x09fb13ebe9642ab578611e6fb03a7f0a340844c144c834cedc057e433b23830c
  Gas price: 0.0 gwei   Gas limit: 6721975   Nonce: 12
  MockV3Aggregator.constructor confirmed   Block: 14   Gas used: 430659 (6.41%)
  MockV3Aggregator deployed at: 0x79f6CdBCdFb5556cf0B8CFc8F496C0605b37Ccc9

Mocks Deployed!
  File "brownie/_cli/run.py", line 50, in main
    return_value, frame = run(
  File "brownie/project/scripts.py", line 103, in run
    return_value = f_locals[method_name](*args, **kwargs)
  File "./scripts/deploy.py", line 29, in main
    deploy_fund_me()
  File "./scripts/deploy.py", line 19, in deploy_fund_me
    fund_me = FundMe.deploy(
  File "brownie/network/contract.py", line 528, in __call__
    return tx["from"].deploy(
  File "brownie/network/account.py", line 509, in deploy
    data = contract.deploy.encode_input(*args)
  File "brownie/network/contract.py", line 557, in encode_input
    data = format_input(self.abi, args)
  File "brownie/convert/normalize.py", line 15, in format_input
    raise TypeError(f"{abi['name']} requires no arguments")
TypeError: constructor requires no arguments

What I've tried

I've run brownie run scripts/deploy.py --network rinkeby to see if the same issue happens, the error message is the same but the mocks aren't being deployed. I've looked at manually adding Rinkeby to the network list but haven't done it yet, as it doesn't seem like the crux of my issue (but is an issue that may not have anything to do with the Type Error constructor one).

I've run brownie run scripts/deploy.py --network ganache-local , and the exact same thing happened as when running brownie run scripts/deploy.py .

I've looked up what the error message means, I understand it has to do with the abi, I assume with a problem in getting the abi? but I can't understand where to go from that information.

I've then run Start Debugging on the deploy.py file, and the first error came from the first line :

Exception has occurred: ImportError
cannot import name 'MockV3Aggregator' from 'brownie' (/home/anne/.local/lib/python3.8/site-packages/brownie/__init__.py)
  File "/home/anne/Documents/Programming/brownie_fund_me-1/scripts/deploy.py", line 1, in <module>
    from brownie import MockV3Aggregator, network, config, FundMe

(the same error comes on the helpful_scripts.py
I've tried changing the Aggregator version, copying/pasting the MockV3Aggregator.sol in the /brownie/ folder, didn't change anything (so I removed it).

I've checked that my brownie-config.yaml is correctly indented and the data is correct :

dependencies:
  # - <organization/repo>@<version>
  - smartcontractkit/[email protected]
compiler:
  solc:
    remappings:
      - "@chainlink=smartcontractkit/[email protected]"
dotenv: .env
networks:
  default: development
  rinkeby:
    eth_usd_price_feed: "0x8A753747A1Fa494EC906cE90E9f37563A8AF630e"
    verify: False
  mainnet-fork-dev:
    eth_usd_price_feed: "0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419"
    verify: False
  development:
    verify: False
  ganache-local:
    host: http://0.0.0.0:8545
    verify: False
wallets:
  from_key: ${PRIVATE_KEY}

I've also noticed that when I run the code brownie run scripts/deploy.py , in brownie/build/contracts/dependencies/smartcontractkit/[email protected], 4 .json files have been created:
AggregatorInterface.json
AggregatorV2V3Interface.json
AggregatorV3Interface.json
SafeMathChainlink.json

My question is, is it normal that 3 different types of Aggregator Interface seem to be working at once? In Patrick's screenshot of his directory, it shows only one.

I've also noticed that in my build/contracts/deployments folder, the folder 8777 was correctly created and filled with the new contract address where the Mocks were deployed running on my ganache-local, but no folder was created when the mocks were created running on ganache-cli. Is it normal?

I'll keep on digging up the issue, seems like it comes from the MockV3Aggregator and/or AggregatorV2V3Interface, but any help would be greatly appreciated.

Files for reference

deploy.py

from brownie import MockV3Aggregator, network, config, FundMe
from scripts.helpful_scripts import (
    get_account,
    deploy_mocks,
    LOCAL_BLOCKCHAIN_ENVIRONMENTS,
)


def deploy_fund_me():
    account = get_account()
    if network.show_active() not in LOCAL_BLOCKCHAIN_ENVIRONMENTS:
        price_feed_address = config["networks"][network.show_active()][
            "eth_usd_price_feed"
        ]
    else:
        deploy_mocks()
        price_feed_address = MockV3Aggregator[-1].address

    fund_me = FundMe.deploy(
        price_feed_address,
        {"from": account},
        publish_source=config["networks"][network.show_active()].get("verify"),
    )
    print(f"Contract deployed to {fund_me.address}")
    return fund_me


def main():
    deploy_fund_me()

helpful_scripts.py

from brownie import network, config, accounts, MockV3Aggregator

FORKED_LOCAL_ENVIRONMENTS = ["mainnet-fork", "mainnet-fork-dev"]
LOCAL_BLOCKCHAIN_ENVIRONMENTS = ["development", "ganache-local"]
DECIMALS = 8
STARTING_PRICE = 200000000000


def get_account():
    if (
        network.show_active() in LOCAL_BLOCKCHAIN_ENVIRONMENTS
        or network.show_active() in FORKED_LOCAL_ENVIRONMENTS
    ):
        return accounts[0]
    else:
        return accounts.add(config["wallets"]["from_key"])


def deploy_mocks():
    print(f"The active network is {network.show_active()}")
    print("Deploying Mocks...")
    if len(MockV3Aggregator) <= 0:
        MockV3Aggregator.deploy(DECIMALS, STARTING_PRICE, {"from": get_account()})
    print("Mocks Deployed!")

FundMe.sol

// SPDX-License-Identifier: MIT

pragma solidity ^0.6.6;

import "@chainlink/contracts/src/v0.6/interfaces/AggregatorV3Interface.sol";
import "@chainlink/contracts/src/v0.6/vendor/SafeMathChainlink.sol";

contract FundMe {
    using SafeMathChainlink for uint256;

    mapping(address => uint256) public addressToAmountFunded;
    address[] public funders;
    address public owner;

    constructor() public {
        owner = msg.sender;
    }

    function fund() public payable {
        uint256 minimumUSD = 50 * 10**18;
        require(
            getConversionRate(msg.value) >= minimumUSD,
            "You need to spend more ETH!"
        );
        addressToAmountFunded[msg.sender] += msg.value;
        funders.push(msg.sender);
    }

    function getVersion() public view returns (uint256) {
        AggregatorV3Interface priceFeed = AggregatorV3Interface(
            0x8A753747A1Fa494EC906cE90E9f37563A8AF630e
        );
        return priceFeed.version();
    }

    function getPrice() public view returns (uint256) {
        AggregatorV3Interface priceFeed = AggregatorV3Interface(
            0x8A753747A1Fa494EC906cE90E9f37563A8AF630e
        );
        (, int256 answer, , , ) = priceFeed.latestRoundData();
        return uint256(answer * 10000000000);
    }

    // 1000000000
    function getConversionRate(uint256 ethAmount)
        public
        view
        returns (uint256)
    {
        uint256 ethPrice = getPrice();
        uint256 ethAmountInUsd = (ethPrice * ethAmount) / 1000000000000000000;
        return ethAmountInUsd;
    }

    modifier onlyOwner() {
        require(msg.sender == owner);
        _;
    }

    function withdraw() public payable onlyOwner {
        msg.sender.transfer(address(this).balance);

        for (
            uint256 funderIndex = 0;
            funderIndex < funders.length;
            funderIndex++
        ) {
            address funder = funders[funderIndex];
            addressToAmountFunded[funder] = 0;
        }
        funders = new address[](0);
    }
}

Test Error

==================================================================== short test summary info ===================================================================== 
FAILED tests/test_api_consumer.py::test_send_api_request_testnet - ValueError: Gas estimation failed: 'invalid opcode: opcode 0xfe not defined'. This transactio...
FAILED tests/test_vrf.py::test_can_request_random_number - ValueError: Gas estimation failed: 'invalid opcode: opcode 0xfe not defined'. This transaction will l...
FAILED tests/test_vrf.py::test_returns_random_number_testnet - ValueError: Gas estimation failed: 'invalid opcode: opcode 0xfe not defined'. This transaction wi...

======================================================= 3 failed, 1 passed, 5 skipped in 84.39s (0:01:24) ========================================================

Use Local Memory Type Variable Instead of Global Storage Type Variable in Event to Save Gas

Hi, we recently have conducted a systematic study about Solidity event usage, evolution, and impact, and we are attempting to build a tool to improve the practice of Solidity event use based on our findings. We have tried our prototype tool on some of the most popular GitHub Solidity repositories, and for your repository, we find a potential optimization of gas consumption arisen from event use.

The point is that when we use emit operation to store the value of a certain variable, local memory type variable would be preferable to global storage type (state) variable if they hold the same value. The reason is that an extra SLOAD operation would be needed to access the variable if it is storage type, and the SLOAD operation costs 800 gas.

For your repository, we find that the following event use can be improved:

  • APIConsumer.sol
    function name:fulfill
    event name:  DataFullfilled
    variable:    volume->_volume
    function fulfill(bytes32 _requestId, uint256 _volume) public recordChainlinkFulfillment(_requestId)
    {
        volume = _volume;
        emit DataFullfilled(volume);
    }

Do you find our results useful? Your reply and invaluable suggestions would be greatly appreciated, and are vital for improving our tool. Thanks a lot for your time!

Little typo in 01_deploy_vrf.py

There is a little typo in the following file :

scripts/vrf_scripts/01_deploy_vrf.py

The deploy function is called :

depoly_vrf()

It should obviously be called :

deploy_vrf()

It's nearly invisible because as it's called the same way in the main function it's still working properly:

def main():
    depoly_vrf()

Have a good day!

Move conftest methods to a helpful_scripts file

get_eth_usd_price_feed_address
get_link_token
get_vrf_coordinator
get_keyhash
get_job_id
get_oracle

And maybe a few others should move to a helpful scripts section. They should do the exact same thing. We should also modularize the funding of contracts into 1 universal script instead of 3.

Cannot Read script on ganache development network

I am seeing that my local testing with ganche-cli is causing some issues connecting to the same network.

Repro steps:

  1. Set the default network in the yanl file to ganache.
  2. Install ganache-cli via npm. Start ganache-cli in one terminal tab.
  3. Open a new terminal tab and add a ganache network. brownie networks add Ethereum ganache host=http://localhost:8545 chainid=1337.
  4. Run the deploy script locally with brownie run scripts/price_feed_scripts/01_deploy_price_consumer_v3.py. Here I was having an issue

$ brownie run scripts/price_feed_scripts/01_deploy_price_consumer_v3.py

Brownie v1.15.1 - Python development framework for Ethereum

ChainlinkMixProject is the active project.
File "brownie/_cli/main.py", line 64, in main
importlib.import_module(f"brownie._cli.{cmd}").main()
File "brownie/_cli/run.py", line 43, in main
network.connect(CONFIG.argv["network"])
File "brownie/network/main.py", line 55, in connect
p._load_deployments()
File "brownie/project/main.py", line 357, in _load_deployments
contract = ProjectContract(self, build, build_json.stem)
File "brownie/network/contract.py", line 1291, in init
_DeployedContractBase.init(self, address, owner, tx)
File "brownie/network/contract.py", line 757, in init
raise ContractNotFound(f"No contract deployed at {address}")
ContractNotFound: No contract deployed at 0xB47a7bDF2C0B546AE73C4352c70BC68B0d479048

  1. I was able to get this to work by running brownie run scripts/price_feed_scripts/01_deploy_price_consumer_v3.py --network development.
  2. I then tried to run the read script and I was not able to brownie run scripts/price_feed_scripts/02_read_price_feed.py

$ brownie run scripts/price_feed_scripts/02_read_price_feed.py

Brownie v1.15.1 - Python development framework for Ethereum

ChainlinkMixProject is the active project.
File "brownie/_cli/main.py", line 64, in main
importlib.import_module(f"brownie._cli.{cmd}").main()
File "brownie/_cli/run.py", line 43, in main
network.connect(CONFIG.argv["network"])
File "brownie/network/main.py", line 55, in connect
p._load_deployments()
File "brownie/project/main.py", line 357, in _load_deployments
contract = ProjectContract(self, build, build_json.stem)
File "brownie/network/contract.py", line 1291, in init
_DeployedContractBase.init(self, address, owner, tx)
File "brownie/network/contract.py", line 757, in init
raise ContractNotFound(f"No contract deployed at {address}")
ContractNotFound: No contract deployed at 0xB47a7bDF2C0B546AE73C4352c70BC68B0d479048

  1. I retried with the network setting and it did not work due to list index out of range in Python and a BrownieEnvironmentWarning of block height.

$ brownie run scripts/price_feed_scripts/02_read_price_feed.py --network development

Brownie v1.15.1 - Python development framework for Ethereum

ChainlinkMixProject is the active project.
/Users/nicklasb/.local/pipx/venvs/eth-brownie/lib/python3.9/site-packages/brownie/network/main.py:44: BrownieEnvironmentWarning: Development network has a block height of 30
warnings.warn(
Attached to local RPC client listening at '127.0.0.1:8545'...

Running 'scripts/price_feed_scripts/02_read_price_feed.py::main'...
File "brownie/_cli/run.py", line 49, in main
return_value, frame = run(
File "brownie/project/scripts.py", line 103, in run
return_value = f_locals[method_name](*args, **kwargs)
File "./scripts/price_feed_scripts/02_read_price_feed.py", line 6, in main
price_feed_contract = PriceFeedConsumer[-1]
File "brownie/network/contract.py", line 160, in getitem
return self._contracts[i]
IndexError: list index out of range

Goerli support

Now we have chainlink at Goerli and Kovan/Ropsten are deprecated, so should we add goerli params to config?

It will be very uesfull. I used these for API calls:

goerli:
        eth_usd_price_feed: "0x8A753747A1Fa494EC906cE90E9f37563A8AF630e"
        fee: 100000000000000000
        fund_amount: 5000000000000000000
        gas_lane: "0xd89b2bf150e3b9e13446986e571fb9cab24b13cea0a43ea20a6049a85cc807cc"
        jobId: 7223acbd01654282865b678924126013
        keyhash: "0x2ed0feb3e7fd2022120aa84fab1945545a9f2ffc9076fd6156fa96eaff4c1311"
        link_token: "0x326C977E6efc84E512bB9C30f76E30c160eD06FB"
        oracle: "0xCC79157eb46F5624204f47AB42b3906cAA40eaB7"
        # Add your sub_id
        # subscription_id: 1003
        verify: true
        vrf_coordinator: "0x2Ca8E0C643bDe4C2E08ab1fA0da3401AdAD7734D"

Typo - ReadMe

"This is a repo to work with and use Chainlink smart contracts in a python environment. If you're brand new to Chainlink, check out the beginer walkthroughs in remix to learn the basics."

beginer -> beginner

Update Solidity Contract to v0.8

To keep up with the latest major release of Solidity (that has a lot of good features that users demand) we should upgrade our contracts to v0.8. At the same time, we should also update the OpenZepplin contracts in the dependencies of the brownie.config to point to the latest version of those contracts since they also use Solidity v0.8.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.