main 3ad93abf50fb cached
20 files
41.2 KB
11.8k tokens
10 symbols
1 requests
Download .txt
Repository: ava-labs/avalanche-smart-contract-quickstart
Branch: main
Commit: 3ad93abf50fb
Files: 20
Total size: 41.2 KB

Directory structure:
gitextract_1nu2uio7/

├── .gitignore
├── LICENSE
├── README.md
├── contracts/
│   ├── ExampleERC20.sol
│   ├── MockContract.sol
│   ├── NFT.sol
│   └── Storage.sol
├── hardhat.config.ts
├── package.json
├── scripts/
│   ├── deploy.ts
│   ├── erc20.ts
│   ├── example.js
│   ├── fund-cchain-addresses.js
│   ├── nft.ts
│   ├── sendAvaxJSONProvider.ts
│   ├── sendAvaxWalletSigner.ts
│   └── storage.ts
├── setup.js
├── test/
│   └── Coin.js
└── tsconfig.json

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
/dist

/.idea
*.tsbuildinfo

.DS_Store

# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*

node_modules/
.env*
!.env*.default
.vscode/*
!.vscode/settings.json.default

cache/
artifacts/

.yalc
yalc.lock

# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
.pnpm-debug.log*

# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage
*.lcov

# nyc test coverage
.nyc_output

# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/

# Snowpack dependency directory (https://snowpack.dev/)
web_modules/

# TypeScript cache
*.tsbuildinfo

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variables file
.env
.env.test
.env.production

# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache

# Next.js build output
.next
out

# Nuxt.js build / generate output
.nuxt
dist

# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public

# vuepress build output
.vuepress/dist

# Serverless directories
.serverless/

# FuseBox cache
.fusebox/

# DynamoDB Local files
.dynamodb/

# TernJS port file
.tern-port

# Stores VSCode versions used for testing VSCode extensions
.vscode-test

# yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*


================================================
FILE: LICENSE
================================================
BSD 3-Clause License

Copyright (c) 2020, Ava Labs, Inc.
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
   list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

3. Neither the name of the copyright holder nor the names of its
   contributors may be used to endorse or promote products derived from
   this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


================================================
FILE: README.md
================================================
## Introduction

Avalanche is an open-source platform for launching decentralized applications and enterprise blockchain deployments in one interoperable, highly scalable ecosystem. Avalanche gives you complete control on both the network and application layers—helping you build anything you can imagine.

The Avalanche Network is composed of many blockchains. One of these blockchains is the C-Chain (Contract Chain), which is an Ethereum Virtual Machine instance. The C-Chain's API is almost identical to an Ethereum node's API. Avalanche offers the same interface as Ethereum but with higher speed, higher throughput, lower fees and lower transaction confirmation times. These properties considerably improve the performance of DApps and the user experience of smart contracts.

The goal of this guide is to lay out best practices regarding writing, testing and deployment of smart contracts to Avalanche's C-Chain. We'll be building smart contracts with development environment [Hardhat](https://hardhat.org).

## Prerequisites

### NodeJS and Yarn

First, install the LTS (long-term support) version of [nodejs](https://nodejs.org/en). This is `14.17.0` at the time of writing. NodeJS bundles `npm`.

Next, install [yarn](https://yarnpkg.com):

```zsh
npm install -g yarn
```

### AvalancheGo and Avash

[AvalancheGo](https://github.com/ava-labs/avalanchego) is an Avalanche node implementation written in Go. [Avash](https://docs.avax.network/build/tools/avash) is a tool to quickly deploy local test networks. Together, you can deploy local test networks and run tests on them.

### Solidity and Avalanche

It is also helpful to have a basic understanding of [Solidity](https://docs.soliditylang.org) and [Avalanche](https://docs.avax.network).

## Dependencies

Clone the [quickstart repository](https://github.com/ava-labs/avalanche-smart-contract-quickstart) and install the necessary packages via `yarn`.

```zsh
$ git clone https://github.com/ava-labs/avalanche-smart-contract-quickstart.git
$ cd avalanche-smart-contract-quickstart
$ yarn
```

## Write Contracts

Edit the `Coin.sol` contract in `contracts/`. `Coin.sol` is an [Open Zeppelin](https://openzeppelin.com) [ERC20](https://eips.ethereum.org/EIPS/eip-20) contract. ERC20 is a popular smart contract interface. You can also add your own contracts.

## Hardhat Config

Hardhat uses `hardhat.config.js` as the configuration file. You can define tasks, networks, compilers and more in that file. For more information see [here](https://hardhat.org/config/).

In our repository we use a pre-configured file [hardhat.config.ts](https://github.com/ava-labs/avalanche-smart-contract-quickstart/blob/main/hardhat.config.ts). This file configures necessary network information to provide smooth interaction with Avalanche. There are also some pre-defined private keys for testing on a local test network.

## Hardhat Tasks

You can define custom hardhat tasks in [hardhat.config.ts](https://github.com/ava-labs/avalanche-smart-contract-quickstart/blob/main/hardhat.config.ts).

## Documentation

There is a documentation under the Avalanche's official documentation repository:
[Using Hardhat with the Avalanche C-Chain](https://docs.avax.network/build/tutorials/smart-contracts/using-hardhat-with-the-avalanche-c-chain)

================================================
FILE: contracts/ExampleERC20.sol
================================================
//SPDX-License-Identifier: MIT
pragma solidity >=0.6.2;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

contract ExampleERC20 is ERC20, Ownable {
  string private TOKEN_NAME = "Example ERC20 Token";
  string private TOKEN_SYMBOL = "XMPL";

  uint256 private constant TOTAL_SUPPLY = 123456789;

  constructor()ERC20(TOKEN_NAME, TOKEN_SYMBOL) {
    _mint(msg.sender, TOTAL_SUPPLY);
  }

  function mint(address to, uint256 amount) public onlyOwner {
    _mint(to, amount);
  }

  function burn(address from, uint256 amount) public onlyOwner {
    _burn(from, amount);
  }
}


================================================
FILE: contracts/MockContract.sol
================================================
//SPDX-License-Identifier: MIT
pragma solidity ^0.6.4;

///////////////////////////////////////////////
// This contract is taken from Gnosis and is
// used to facilitate unit testing. It should
// not be deployed in production.
///////////////////////////////////////////////

interface MockInterface {
  /**
   * @dev After calling this method, the mock will return `response` when it is called
   * with any calldata that is not mocked more specifically below
   * (e.g. using givenMethodReturn).
   * @param response ABI encoded response that will be returned if method is invoked
   */
  function givenAnyReturn(bytes calldata response) external;

  function givenAnyReturnBool(bool response) external;

  function givenAnyReturnUint(uint256 response) external;

  function givenAnyReturnAddress(address response) external;

  function givenAnyRevert() external;

  function givenAnyRevertWithMessage(string calldata message) external;

  function givenAnyRunOutOfGas() external;

  /**
   * @dev After calling this method, the mock will return `response` when the given
   * methodId is called regardless of arguments. If the methodId and arguments
   * are mocked more specifically (using `givenMethodAndArguments`) the latter
   * will take precedence.
   * @param method ABI encoded methodId. It is valid to pass full calldata (including arguments). The mock will extract the methodId from it
   * @param response ABI encoded response that will be returned if method is invoked
   */
  function givenMethodReturn(bytes calldata method, bytes calldata response)
    external;

  function givenMethodReturnBool(bytes calldata method, bool response) external;

  function givenMethodReturnUint(bytes calldata method, uint256 response)
    external;

  function givenMethodReturnAddress(bytes calldata method, address response)
    external;

  function givenMethodRevert(bytes calldata method) external;

  function givenMethodRevertWithMessage(
    bytes calldata method,
    string calldata message
  ) external;

  function givenMethodRunOutOfGas(bytes calldata method) external;

  /**
   * @dev After calling this method, the mock will return `response` when the given
   * methodId is called with matching arguments. These exact calldataMocks will take
   * precedence over all other calldataMocks.
   * @param call ABI encoded calldata (methodId and arguments)
   * @param response ABI encoded response that will be returned if contract is invoked with calldata
   */
  function givenCalldataReturn(bytes calldata call, bytes calldata response)
    external;

  function givenCalldataReturnBool(bytes calldata call, bool response) external;

  function givenCalldataReturnUint(bytes calldata call, uint256 response)
    external;

  function givenCalldataReturnAddress(bytes calldata call, address response)
    external;

  function givenCalldataRevert(bytes calldata call) external;

  function givenCalldataRevertWithMessage(
    bytes calldata call,
    string calldata message
  ) external;

  function givenCalldataRunOutOfGas(bytes calldata call) external;

  /**
   * @dev Returns the number of times anything has been called on this mock since last reset
   */
  function invocationCount() external returns (uint256);

  /**
   * @dev Returns the number of times the given method has been called on this mock since last reset
   * @param method ABI encoded methodId. It is valid to pass full calldata (including arguments). The mock will extract the methodId from it
   */
  function invocationCountForMethod(bytes calldata method)
    external
    returns (uint256);

  /**
   * @dev Returns the number of times this mock has been called with the exact calldata since last reset.
   * @param call ABI encoded calldata (methodId and arguments)
   */
  function invocationCountForCalldata(bytes calldata call)
    external
    returns (uint256);

  /**
   * @dev Resets all mocked methods and invocation counts.
   */
  function reset() external;
}

/**
 * Implementation of the MockInterface.
 */
contract MockContract is MockInterface {
  enum MockType {
    Return,
    Revert,
    OutOfGas
  }

  bytes32 public constant MOCKS_LIST_START = hex"01";
  bytes public constant MOCKS_LIST_END = "0xff";
  bytes32 public constant MOCKS_LIST_END_HASH = keccak256(MOCKS_LIST_END);
  bytes4 public constant SENTINEL_ANY_MOCKS = hex"01";
  bytes public constant DEFAULT_FALLBACK_VALUE = abi.encode(false);

  // A linked list allows easy iteration and inclusion checks
  mapping(bytes32 => bytes) calldataMocks;
  mapping(bytes => MockType) calldataMockTypes;
  mapping(bytes => bytes) calldataExpectations;
  mapping(bytes => string) calldataRevertMessage;
  mapping(bytes32 => uint256) calldataInvocations;

  mapping(bytes4 => bytes4) methodIdMocks;
  mapping(bytes4 => MockType) methodIdMockTypes;
  mapping(bytes4 => bytes) methodIdExpectations;
  mapping(bytes4 => string) methodIdRevertMessages;
  mapping(bytes32 => uint256) methodIdInvocations;

  MockType fallbackMockType;
  bytes fallbackExpectation = DEFAULT_FALLBACK_VALUE;
  string fallbackRevertMessage;
  uint256 invocations;
  uint256 resetCount;

  constructor() public {
    calldataMocks[MOCKS_LIST_START] = MOCKS_LIST_END;
    methodIdMocks[SENTINEL_ANY_MOCKS] = SENTINEL_ANY_MOCKS;
  }

  function trackCalldataMock(bytes memory call) private {
    bytes32 callHash = keccak256(call);
    if (calldataMocks[callHash].length == 0) {
      calldataMocks[callHash] = calldataMocks[MOCKS_LIST_START];
      calldataMocks[MOCKS_LIST_START] = call;
    }
  }

  function trackMethodIdMock(bytes4 methodId) private {
    if (methodIdMocks[methodId] == 0x0) {
      methodIdMocks[methodId] = methodIdMocks[SENTINEL_ANY_MOCKS];
      methodIdMocks[SENTINEL_ANY_MOCKS] = methodId;
    }
  }

  function _givenAnyReturn(bytes memory response) internal {
    fallbackMockType = MockType.Return;
    fallbackExpectation = response;
  }

  function givenAnyReturn(bytes calldata response) external override {
    _givenAnyReturn(response);
  }

  function givenAnyReturnBool(bool response) external override {
    uint256 flag = response ? 1 : 0;
    _givenAnyReturn(uintToBytes(flag));
  }

  function givenAnyReturnUint(uint256 response) external override {
    _givenAnyReturn(uintToBytes(response));
  }

  function givenAnyReturnAddress(address response) external override {
    _givenAnyReturn(uintToBytes(uint256(response)));
  }

  function givenAnyRevert() external override {
    fallbackMockType = MockType.Revert;
    fallbackRevertMessage = "";
  }

  function givenAnyRevertWithMessage(string calldata message)
    external
    override
  {
    fallbackMockType = MockType.Revert;
    fallbackRevertMessage = message;
  }

  function givenAnyRunOutOfGas() external override {
    fallbackMockType = MockType.OutOfGas;
  }

  function _givenCalldataReturn(bytes memory call, bytes memory response)
    private
  {
    calldataMockTypes[call] = MockType.Return;
    calldataExpectations[call] = response;
    trackCalldataMock(call);
  }

  function givenCalldataReturn(bytes calldata call, bytes calldata response)
    external
    override
  {
    _givenCalldataReturn(call, response);
  }

  function givenCalldataReturnBool(bytes calldata call, bool response)
    external
    override
  {
    uint256 flag = response ? 1 : 0;
    _givenCalldataReturn(call, uintToBytes(flag));
  }

  function givenCalldataReturnUint(bytes calldata call, uint256 response)
    external
    override
  {
    _givenCalldataReturn(call, uintToBytes(response));
  }

  function givenCalldataReturnAddress(bytes calldata call, address response)
    external
    override
  {
    _givenCalldataReturn(call, uintToBytes(uint256(response)));
  }

  function _givenMethodReturn(bytes memory call, bytes memory response)
    private
  {
    bytes4 method = bytesToBytes4(call);
    methodIdMockTypes[method] = MockType.Return;
    methodIdExpectations[method] = response;
    trackMethodIdMock(method);
  }

  function givenMethodReturn(bytes calldata call, bytes calldata response)
    external
    override
  {
    _givenMethodReturn(call, response);
  }

  function givenMethodReturnBool(bytes calldata call, bool response)
    external
    override
  {
    uint256 flag = response ? 1 : 0;
    _givenMethodReturn(call, uintToBytes(flag));
  }

  function givenMethodReturnUint(bytes calldata call, uint256 response)
    external
    override
  {
    _givenMethodReturn(call, uintToBytes(response));
  }

  function givenMethodReturnAddress(bytes calldata call, address response)
    external
    override
  {
    _givenMethodReturn(call, uintToBytes(uint256(response)));
  }

  function givenCalldataRevert(bytes calldata call) external override {
    calldataMockTypes[call] = MockType.Revert;
    calldataRevertMessage[call] = "";
    trackCalldataMock(call);
  }

  function givenMethodRevert(bytes calldata call) external override {
    bytes4 method = bytesToBytes4(call);
    methodIdMockTypes[method] = MockType.Revert;
    trackMethodIdMock(method);
  }

  function givenCalldataRevertWithMessage(
    bytes calldata call,
    string calldata message
  ) external override {
    calldataMockTypes[call] = MockType.Revert;
    calldataRevertMessage[call] = message;
    trackCalldataMock(call);
  }

  function givenMethodRevertWithMessage(
    bytes calldata call,
    string calldata message
  ) external override {
    bytes4 method = bytesToBytes4(call);
    methodIdMockTypes[method] = MockType.Revert;
    methodIdRevertMessages[method] = message;
    trackMethodIdMock(method);
  }

  function givenCalldataRunOutOfGas(bytes calldata call) external override {
    calldataMockTypes[call] = MockType.OutOfGas;
    trackCalldataMock(call);
  }

  function givenMethodRunOutOfGas(bytes calldata call) external override {
    bytes4 method = bytesToBytes4(call);
    methodIdMockTypes[method] = MockType.OutOfGas;
    trackMethodIdMock(method);
  }

  function invocationCount() external override returns (uint256) {
    return invocations;
  }

  function invocationCountForMethod(bytes calldata call)
    external
    override
    returns (uint256)
  {
    bytes4 method = bytesToBytes4(call);
    return methodIdInvocations[keccak256(abi.encodePacked(resetCount, method))];
  }

  function invocationCountForCalldata(bytes calldata call)
    external
    override
    returns (uint256)
  {
    return calldataInvocations[keccak256(abi.encodePacked(resetCount, call))];
  }

  function reset() external override {
    // Reset all exact calldataMocks
    bytes memory nextMock = calldataMocks[MOCKS_LIST_START];
    bytes32 mockHash = keccak256(nextMock);
    // We cannot compary bytes
    while (mockHash != MOCKS_LIST_END_HASH) {
      // Reset all mock maps
      calldataMockTypes[nextMock] = MockType.Return;
      calldataExpectations[nextMock] = hex"";
      calldataRevertMessage[nextMock] = "";
      // Set next mock to remove
      nextMock = calldataMocks[mockHash];
      // Remove from linked list
      calldataMocks[mockHash] = "";
      // Update mock hash
      mockHash = keccak256(nextMock);
    }
    // Clear list
    calldataMocks[MOCKS_LIST_START] = MOCKS_LIST_END;

    // Reset all any calldataMocks
    bytes4 nextAnyMock = methodIdMocks[SENTINEL_ANY_MOCKS];
    while (nextAnyMock != SENTINEL_ANY_MOCKS) {
      bytes4 currentAnyMock = nextAnyMock;
      methodIdMockTypes[currentAnyMock] = MockType.Return;
      methodIdExpectations[currentAnyMock] = hex"";
      methodIdRevertMessages[currentAnyMock] = "";
      nextAnyMock = methodIdMocks[currentAnyMock];
      // Remove from linked list
      methodIdMocks[currentAnyMock] = 0x0;
    }
    // Clear list
    methodIdMocks[SENTINEL_ANY_MOCKS] = SENTINEL_ANY_MOCKS;

    fallbackExpectation = DEFAULT_FALLBACK_VALUE;
    fallbackMockType = MockType.Return;
    invocations = 0;
    resetCount += 1;
  }

  function useAllGas() private {
    while (true) {
      bool s;
      assembly {
        //expensive call to EC multiply contract
        s := call(sub(gas(), 2000), 6, 0, 0x0, 0xc0, 0x0, 0x60)
      }
    }
  }

  function bytesToBytes4(bytes memory b) private pure returns (bytes4) {
    bytes4 out;
    for (uint256 i = 0; i < 4; i++) {
      out |= bytes4(b[i] & 0xFF) >> (i * 8);
    }
    return out;
  }

  function uintToBytes(uint256 x) private pure returns (bytes memory b) {
    b = new bytes(32);
    assembly {
      mstore(add(b, 32), x)
    }
  }

  function updateInvocationCount(bytes4 methodId, bytes memory originalMsgData)
    public
  {
    require(
      msg.sender == address(this),
      "Can only be called from the contract itself"
    );
    invocations += 1;
    methodIdInvocations[keccak256(abi.encodePacked(resetCount, methodId))] += 1;
    calldataInvocations[
      keccak256(abi.encodePacked(resetCount, originalMsgData))
    ] += 1;
  }

  fallback() external payable {
    bytes4 methodId;
    assembly {
      methodId := calldataload(0)
    }

    // First, check exact matching overrides
    if (calldataMockTypes[msg.data] == MockType.Revert) {
      revert(calldataRevertMessage[msg.data]);
    }
    if (calldataMockTypes[msg.data] == MockType.OutOfGas) {
      useAllGas();
    }
    bytes memory result = calldataExpectations[msg.data];

    // Then check method Id overrides
    if (result.length == 0) {
      if (methodIdMockTypes[methodId] == MockType.Revert) {
        revert(methodIdRevertMessages[methodId]);
      }
      if (methodIdMockTypes[methodId] == MockType.OutOfGas) {
        useAllGas();
      }
      result = methodIdExpectations[methodId];
    }

    // Last, use the fallback override
    if (result.length == 0) {
      if (fallbackMockType == MockType.Revert) {
        revert(fallbackRevertMessage);
      }
      if (fallbackMockType == MockType.OutOfGas) {
        useAllGas();
      }
      result = fallbackExpectation;
    }

    // Record invocation as separate call so we don't rollback in case we are called with STATICCALL
    (, bytes memory r) = address(this).call{ gas: 100000 }(
      abi.encodeWithSignature(
        "updateInvocationCount(bytes4,bytes)",
        methodId,
        msg.data
      )
    );
    assert(r.length == 0);

    assembly {
      return(add(0x20, result), mload(result))
    }
  }
}


================================================
FILE: contracts/NFT.sol
================================================
//SPDX-License-Identifier: MIT
// contracts/ERC721.sol

pragma solidity >=0.6.2;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/utils/Counters.sol";

contract NFT is ERC721 {
  using Counters for Counters.Counter;
  Counters.Counter private _tokenIds;

  constructor() ERC721("GameItem", "ITM") {}

  // commented out unused variable
  // function awardItem(address player, string memory tokenURI)
  function awardItem(address player)
    public
    returns (uint256)
  {
    _tokenIds.increment();

    uint256 newItemId = _tokenIds.current();
    _mint(player, newItemId);
    // _setTokenURI(newItemId, tokenURI);

    return newItemId;
  }
}


================================================
FILE: contracts/Storage.sol
================================================
//SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;

contract Storage {
  uint256 number;

  function store(uint256 num) public {
    number = num;
  }

  function retrieve() public view returns (uint256) {
    return number;
  }
}


================================================
FILE: hardhat.config.ts
================================================
import { task } from "hardhat/config"
import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers"
import { BigNumber } from "ethers"
import "@nomiclabs/hardhat-waffle"

// When using the hardhat network, you may choose to fork Fuji or Avalanche Mainnet
// This will allow you to debug contracts using the hardhat network while keeping the current network state
// To enable forking, turn one of these booleans on, and then run your tasks/scripts using ``--network hardhat``
// For more information go to the hardhat guide
// https://hardhat.org/hardhat-network/
// https://hardhat.org/guides/mainnet-forking.html
const FORK_FUJI = false
const FORK_MAINNET = false
const forkingData = FORK_FUJI ? {
  url: 'https://api.avax-test.network/ext/bc/C/rpc',
} : FORK_MAINNET ? {
  url: 'https://api.avax.network/ext/bc/C/rpc'
} : undefined

task("accounts", "Prints the list of accounts", async (args, hre): Promise<void> => {
  const accounts: SignerWithAddress[] = await hre.ethers.getSigners()
  accounts.forEach((account: SignerWithAddress): void => {
    console.log(account.address)
  })
})

task("balances", "Prints the list of AVAX account balances", async (args, hre): Promise<void> => {
  const accounts: SignerWithAddress[] = await hre.ethers.getSigners()
  for(const account of accounts){
    const balance: BigNumber = await hre.ethers.provider.getBalance(
      account.address
    );
    console.log(`${account.address} has balance ${balance.toString()}`);
  }
})

export default {
  solidity: {
    compilers: [
      {
        version: "0.5.16"
      },
      {
        version: "0.6.2"
      },
      {
        version: "0.6.4"
      },
      {
        version: "0.7.0"
      },
      {
        version: "0.8.0"
      }
    ]
  },
  networks: {
    hardhat: {
      gasPrice: 225000000000,
      chainId: !forkingData ? 43112 : undefined, //Only specify a chainId if we are not forking
      forking: forkingData
    },
    local: {
      url: 'http://localhost:9650/ext/bc/C/rpc',
      gasPrice: 225000000000,
      chainId: 43112,
      accounts: [
        "0x56289e99c94b6912bfc12adc093c9b51124f0dc54ac7a766b2bc5ccf558d8027",
        "0x7b4198529994b0dc604278c99d153cfd069d594753d471171a1d102a10438e07",
        "0x15614556be13730e9e8d6eacc1603143e7b96987429df8726384c2ec4502ef6e",
        "0x31b571bf6894a248831ff937bb49f7754509fe93bbd2517c9c73c4144c0e97dc",
        "0x6934bef917e01692b789da754a0eae31a8536eb465e7bff752ea291dad88c675",
        "0xe700bdbdbc279b808b1ec45f8c2370e4616d3a02c336e68d85d4668e08f53cff",
        "0xbbc2865b76ba28016bc2255c7504d000e046ae01934b04c694592a6276988630",
        "0xcdbfd34f687ced8c6968854f8a99ae47712c4f4183b78dcc4a903d1bfe8cbf60",
        "0x86f78c5416151fe3546dece84fda4b4b1e36089f2dbc48496faf3a950f16157c",
        "0x750839e9dbbd2a0910efe40f50b2f3b2f2f59f5580bb4b83bd8c1201cf9a010a"
      ]
    },
    fuji: {
      url: 'https://api.avax-test.network/ext/bc/C/rpc',
      gasPrice: 225000000000,
      chainId: 43113,
      accounts: []
    },
    mainnet: {
      url: 'https://api.avax.network/ext/bc/C/rpc',
      gasPrice: 225000000000,
      chainId: 43114,
      accounts: []
    }
  }
}

================================================
FILE: package.json
================================================
{
  "name": "avalanche-smart-contract-quickstart",
  "devDependencies": {
    "@nomiclabs/hardhat-ethers": "^2.0.2",
    "@nomiclabs/hardhat-waffle": "^2.0.1",
    "@openzeppelin/contracts": "^4.3.0",
    "@types/chai": "^4.2.21",
    "@types/mocha": "^9.0.0",
    "@types/node": "^16.7.1",
    "avalanche": "3.8.5",
    "chai": "^4.3.4",
    "ethereum-waffle": "^3.4.0",
    "ethereumjs-tx": "^2.1.2",
    "ethers": "^5.4.5",
    "hardhat": "2.6.1",
    "ts-node": "^10.2.1",
    "web3": "^1.5.2"
  },
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "repository": "https://github.com/ava-labs/avalanche-smart-contract-quickstart",
  "author": "Connor Daly <connor.daly@avalabs.org>",
  "contributors": [
    "Gabriel Cardona <gabriel@avalabs.org>"
  ],
  "license": "BSD-3-Clause",
  "scripts": {
    "precompile": "rimraf ./build/",
    "compile": "npx hardhat compile",
    "console": "npx hardhat console",
    "pretest": "yarn compile",
    "test": "npx hardhat test",
    "deploy": "npx hardhat run scripts/deploy.ts",
    "erc20": "npx hardhat run scripts/erc20.ts",
    "nft": "npx hardhat run scripts/nft.ts --network mainnet",
    "storage": "npx hardhat run scripts/storage.ts",
    "send-avax-wallet-signer": "npx hardhat run scripts/sendAvaxWalletSigner.ts",
    "send-avax-json-provider": "npx hardhat run scripts/sendAvaxJSONProvider.ts",
    "lint": "prettier ./test/**/*.ts --check",
    "prepublishOnly": "yarn test",
    "hardhat": "npx hardhat",
    "accounts": "npx hardhat accounts",
    "balances": "npx hardhat balances",
    "fund-cchain-addresses": "npx hardhat run scripts/fund-cchain-addresses.js"
  },
  "dependencies": {
    "typescript": "^4.5.4"
  },
  "engines": {
    "node": ">=14.17.0"
  }
}


================================================
FILE: scripts/deploy.ts
================================================
import { 
  Contract, 
  ContractFactory 
} from "ethers"
import { ethers } from "hardhat"

const main = async(): Promise<any> => {
  const Coin: ContractFactory = await ethers.getContractFactory("ExampleERC20")
  const coin: Contract = await Coin.deploy()

  await coin.deployed()
  console.log(`Coin deployed to: ${coin.address}`)
}

main()
.then(() => process.exit(0))
.catch(error => {
  console.error(error)
  process.exit(1)
})


================================================
FILE: scripts/erc20.ts
================================================
import {
  BigNumber,
  Contract
} from "ethers"
import { ethers } from "hardhat"

const coinName: string = ""
const coinAddr: string = ""
const walletAddress: string = ""

const main = async (): Promise<any> => {
  const contract: Contract = await ethers.getContractAt(coinName, coinAddr)
  const contractAddress: string = contract.address
  console.log(`Address: ${contractAddress}`)

  const name: string = await contract.name()
  console.log(`Name: ${name}`)

  const symbol: string = await contract.symbol()
  console.log(`Symbol: ${symbol}`)

  const decimals: string = await contract.decimals()
  console.log(`Decimals: ${decimals}`)

  const balance: BigNumber = await contract.balanceOf(walletAddress)
  console.log(`Balance of ${walletAddress}: ${balance.toString()}`)

  let totalSupply: BigNumber = await contract.totalSupply()
  console.log(`Total supply: ${totalSupply.toString()}`)

  console.log(`-----MINTING-----`)
  await contract.mint(walletAddress, totalSupply)

  totalSupply = await contract.totalSupply()
  console.log(`Total supply: ${totalSupply.toString()}`)

  console.log(`-----BURNING-----`)
  await contract.burn(walletAddress, totalSupply)

  totalSupply = await contract.totalSupply()
  console.log(`Total supply: ${totalSupply.toString()}`)

  const tx = await contract.transfer(walletAddress, balance)
  console.log("--TX--")
  console.log(tx)

  const txReceipt = await tx.wait()
  console.log("--TX RECEIPT--")
  console.log(txReceipt)
}

main()
  .then(() => process.exit(0))
  .catch(error => {
    console.error(error)
    process.exit(1)
  })

================================================
FILE: scripts/example.js
================================================
const { Contract } = require("ethers");
const hre = require("hardhat");

// TODO: Enter your deployed contract address
const COIN_ADDR = "0x0000000000000000000000000000000000000000";

/**
 * Empty. Try calling some functions here.
 */
async function main() {

}

/**
 * Takes a transaction response and calculates the amount of gas used and converts 
 * it to AVAX. Prints results to console.
 * 
 * @param {TransactionResponse} tx transactionn to extract gas info from
 * @param {string} methodName Name of method to print
 */
async function calculateGasFee(tx, methodName) {
    const gasPrice = 470000000000;
    const weiPerAvax = Number('1000000000000000000');

    const txReceipt = await tx.wait();
    const gasUsed = txReceipt.gasUsed.toString()
    const avax = gasUsed * gasPrice / weiPerAvax;
    console.log(methodName, "gas used:", gasUsed);
    console.log(methodName, "AVAX cost:", avax);
}

/**
 * Calls transfer on the provided contract. Transfers the ERC20 from the from signer 
 * to the to signer for the amount of amount.
 * 
 * @param {Signer} from signer to send from
 * @param {Signer} to signer to send to
 * @param {number} amount amount to send
 * @param {Contract} coinContract ERC20 contract to call
 */
async function sendERC20(from, to, amount, coinContract) {
    const coin = coinContract.connect(from);
    tx = await coin.transfer(to.getAddress(), amount);
    
    await calculateGasFee(tx, "Transfer");
    
}

// We recommend this pattern to be able to use async/await everywhere
// and properly handle errors.
main()
  .then(() => process.exit(0))
  .catch(error => {
    console.error(error);
    process.exit(1);
  });

================================================
FILE: scripts/fund-cchain-addresses.js
================================================
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
const avalanche_1 = require('avalanche');
const avm_1 = require('avalanche/dist/apis/avm');
const evm_1 = require('avalanche/dist/apis/evm');
const utils_1 = require('avalanche/dist/utils');
const sleep = (ms) => {
  return new Promise((resolve) => setTimeout(resolve, ms));
};
const ip = 'localhost';
const port = 9650;
const protocol = 'http';
const networkID = 12345;
const avalanche = new avalanche_1.Avalanche(ip, port, protocol, networkID);
const mstimeout = 3000;
const xchain = avalanche.XChain();
const cchain = avalanche.CChain();
const bintools = avalanche_1.BinTools.getInstance();
const xKeychain = xchain.keyChain();
const cKeychain = cchain.keyChain();
const privKeys = [
  'PrivateKey-ewoqjP7PxY4yr3iLTpLisriqt94hdyDFNgchSxGGztUrTXtNN',
  'PrivateKey-wHR4zmr9am94KVYnV2aRR4QXt78cuGebt1GpYNwJYEbfAGonj',
  'PrivateKey-AR874kuHtHpDk7ntffuEQ9cwiQLL2dz1DmJankW1EyXnz5fc7',
  'PrivateKey-Ntk8vV7zaWzAot2wuDXK4e9ZGFUnU49AYTDew5XUyYaNz2u9d',
  'PrivateKey-oLM8XbXxXmBHVbdKm2tRYQ1WdMj3b2NggftQpvDUXWSMtdY4i',
  'PrivateKey-2kjfDc9RVUQJnu3HQDGiVdxvhM9BmR3UTx7Aq8AJ82G2MspATy',
  'PrivateKey-2Rh5Gtu28ca7PS6rLfN6uou9ext8Y5xhoAJDdWPU7GESBLHtv6',
  'PrivateKey-2ZcbEPKkXjswsNRBGViGzruReAtTAxW9hsGeMc2GgppnJnDgne',
  'PrivateKey-22SYvqaRgFtPJfiZmswrCyE57UcssLVnNPDJ48PYAiCjKVAGy7',
  'PrivateKey-tYRsRPijLo6KD2azMLzkcB2ZUndU3a2dJ8kEqBtqesa85pWhB'
];
privKeys.forEach((privKey) => {
  xKeychain.importKey(privKey);
  cKeychain.importKey(privKey);
});
const xAddresses = xchain.keyChain().getAddresses();
const xAddressStrings = xchain.keyChain().getAddressStrings();
const cAddressStrings = cchain.keyChain().getAddressStrings();
const cAddresses = cchain.keyChain().getAddresses();
const cHexAddresses = [
  '0x8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC',
  '0x9632a79656af553f58738b0fb750320158495942',
  '0x55ee05df718f1a5c1441e76190eb1a19ee2c9430',
  '0x4cf2ed3665f6bfa95ce6a11cfdb7a2ef5fc1c7e4',
  '0x0b891db1901d4875056896f28b6665083935c7a8',
  '0x01f253be2ebf0bd64649fa468bf7b95ca933bde2',
  '0x78A23300E04FB5d5D2820E23cc679738982e1fd5',
  '0x3c7dae394bbf8e9ee1359ad14c1c47003bd06293',
  '0x61e0b3cd93f36847abbd5d40d6f00a8ec6f3cffb',
  '0x0fa8ea536be85f32724d57a37758761b86416123'
];
const cChainBlockchainID = utils_1.Defaults.network['12345'].C.blockchainID;
const cChainBlockchainIdBuf = bintools.cb58Decode(cChainBlockchainID);
const xChainBlockchainID = utils_1.Defaults.network['12345'].X.blockchainID;
const xChainBlockchainIdBuf = bintools.cb58Decode(xChainBlockchainID);
const exportedOuts = [];
const outputs = [];
const inputs = [];
const importedIns = [];
const evmOutputs = [];
const fee = xchain.getDefaultTxFee();
const locktime = new avalanche_1.BN(0);
const threshold = 1;
const memo = bintools.stringToBuffer(
  'AVM utility method buildExportTx to export AVAX to the C-Chain from the X-Chain'
);

const waitForUtxo = async () => {
  const u = await cchain.getUTXOs(cAddressStrings[0], 'X');

  if (u.utxos.getAllUTXOs().length) {
    return u.utxos.getAllUTXOs();
  } else {
    await sleep(mstimeout);
    return waitForUtxo();
  }
};

const main = async () => {
  const avaxAssetID = await xchain.getAVAXAssetID();
  const getBalanceResponse = await xchain.getBalance(
    xAddressStrings[0],
    bintools.cb58Encode(avaxAssetID)
  );
  const balance = new avalanche_1.BN(getBalanceResponse.balance);
  const avmUTXOResponse = await xchain.getUTXOs(xAddressStrings);
  const avmUTXOSet = avmUTXOResponse.utxos;
  const avmUTXOs = avmUTXOSet.getAllUTXOs();
  // 1,000 AVAX
  const amount = new avalanche_1.BN(1000000000000);
  console.log('Exporting 1000 AVAX to each address on the C-Chain...');
  let secpTransferOutput = new avm_1.SECPTransferOutput(
    amount.mul(new avalanche_1.BN(10)),
    [cAddresses[0]],
    locktime,
    threshold
  );
  let transferableOutput = new avm_1.TransferableOutput(
    avaxAssetID,
    secpTransferOutput
  );
  exportedOuts.push(transferableOutput);
  secpTransferOutput = new avm_1.SECPTransferOutput(
    balance.sub(amount.mul(new avalanche_1.BN(10))).sub(fee),
    xAddresses,
    locktime,
    threshold
  );
  transferableOutput = new avm_1.TransferableOutput(
    avaxAssetID,
    secpTransferOutput
  );
  outputs.push(transferableOutput);
  avmUTXOs.forEach((utxo) => {
    const amountOutput = utxo.getOutput();
    const amt = amountOutput.getAmount().clone();
    const txid = utxo.getTxID();
    const outputidx = utxo.getOutputIdx();
    const secpTransferInput = new avm_1.SECPTransferInput(amt);
    secpTransferInput.addSignatureIdx(0, xAddresses[0]);
    const input = new avm_1.TransferableInput(
      txid,
      outputidx,
      avaxAssetID,
      secpTransferInput
    );
    inputs.push(input);
  });

  const exportTx = new avm_1.ExportTx(
    networkID,
    bintools.cb58Decode(xChainBlockchainID),
    outputs,
    inputs,
    memo,
    bintools.cb58Decode(cChainBlockchainID),
    exportedOuts
  );
  const avmUnsignedTx = new avm_1.UnsignedTx(exportTx);
  const avmTx = avmUnsignedTx.sign(xKeychain);
  const avmTXID = await xchain.issueTx(avmTx);
  console.log(avmTXID);
  await sleep(mstimeout);
  console.log('Importing AVAX to the C-Chain...');
  console.log('Please wait');
  const utxos = await waitForUtxo();

  utxos.forEach((utxo, index) => {
    const assetID = utxo.getAssetID();
    const txid = utxo.getTxID();
    const outputidx = utxo.getOutputIdx();
    const output = utxo.getOutput();
    const amt = output.getAmount().clone();
    const input = new evm_1.SECPTransferInput(amt);
    input.addSignatureIdx(0, cAddresses[0]);
    const xferin = new evm_1.TransferableInput(txid, outputidx, assetID, input);
    importedIns.push(xferin);

    cHexAddresses.forEach((cHexAddress) => {
      const evmOutput = new evm_1.EVMOutput(
        cHexAddress,
        new avalanche_1.BN(1000000000),
        assetID
      );
      evmOutputs.push(evmOutput);
    });
  });

  const importTx = new evm_1.ImportTx(
    networkID,
    cChainBlockchainIdBuf,
    xChainBlockchainIdBuf,
    importedIns,
    evmOutputs
  );
  const evmUnsignedTx = new evm_1.UnsignedTx(importTx);

  const evmTx = evmUnsignedTx.sign(cKeychain);
  const evmTXID = await cchain.issueTx(evmTx);
  console.log(evmTXID);
};
main();


================================================
FILE: scripts/nft.ts
================================================
import { Contract } from "ethers"
import { ethers } from "hardhat"
import { abi } from "../artifacts/contracts/NFT.sol/NFT.json"

const coinAddr: string = "0xe304EDd5C4e590e2b8ce08b9625597FF38192D71"
const main = async (): Promise<any> => {
  const contract: Contract = new Contract(coinAddr, abi, ethers.provider)
  const tokenID: number = 395
  const tokenURI = await contract.tokenURI(tokenID)
  console.log(tokenURI)
}

main()
  .then(() => process.exit(0))
  .catch(error => {
    console.error(error)
    process.exit(1)
  })

================================================
FILE: scripts/sendAvaxJSONProvider.ts
================================================
import { utils } from "ethers"
import { ethers } from "hardhat"
interface Param {
  from: string
  to: string 
  value: string
}

const main = async(): Promise<any> => {
  const from: string = "0x8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC"
  const to: string = "0xDd1749831fbF70d88AB7bB07ef7CD9c53D054a57"
  const amount: string = "0.01"
  const params: Param[] = [{
    from: from,
    to: to,
    value: utils.parseUnits(amount, "ether").toHexString()
  }]
  const tx: any = await ethers.provider.send("eth_sendTransaction", params)
  console.log(tx)
}

main()
.then(() => process.exit(0))
.catch(error => {
  console.error(error)
  process.exit(1)
})

================================================
FILE: scripts/sendAvaxWalletSigner.ts
================================================
import { 
  BigNumber,
  providers,
  utils,
  Wallet
} from "ethers"

const walletAddress: string = "0xDd1749831fbF70d88AB7bB07ef7CD9c53D054a57"
const pk: string = "0x56289e99c94b6912bfc12adc093c9b51124f0dc54ac7a766b2bc5ccf558d8027"
const protocol: string = "http"
const host: string = "localhost"
const port: number = 9650

const main = async(): Promise<any> => {
  const provider: providers.JsonRpcProvider = new providers.JsonRpcProvider(`${protocol}://${host}:${port}/ext/bc/C/rpc`)
  const num: number = await provider.getBlockNumber()
  console.log(num)

  const balance: BigNumber = await provider.getBalance(walletAddress)
  console.log(balance)

  const formatted: string = utils.formatEther(balance)
  console.log(formatted)

  const parsed: BigNumber = utils.parseEther("1.0")
  console.log(parsed)

  const wallet: Wallet = new Wallet(pk, provider)
  const tx: providers.TransactionResponse = await wallet.sendTransaction({ 
    to: walletAddress, 
    value: parsed
  });
  console.log(tx)
}

main()
.then(() => process.exit(0))
.catch(error => {
  console.error(error)
  process.exit(1)
})

================================================
FILE: scripts/storage.ts
================================================
import { 
  BigNumber,
  Contract
} from "ethers"
import { ethers } from "hardhat"

const contractName: string = "Storage"
const contractAddress: string = "0xE3573540ab8A1C4c754Fd958Dc1db39BBE81b208"

const main = async(): Promise<any> => {
  const contract: Contract = await ethers.getContractAt(contractName, contractAddress)
  const num: BigNumber = await contract.retrieve()
  console.log(`Number: ${num.toString()}`)
  const tx = await contract.store(507)
  console.log(tx)
}

main()

================================================
FILE: setup.js
================================================
const hardhat = require("hardhat")
const Web3 = require("web3")


================================================
FILE: test/Coin.js
================================================
// test/Airdrop.js
// Load dependencies
const { expect } = require('chai');
const { BigNumber } = require('ethers');
const { ethers } = require('hardhat');
const Web3 = require('web3');

const OWNER_ADDRESS = ethers.utils.getAddress("0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266");

const DECIMALS = 2;

const AMT = 150

///////////////////////////////////////////////////////////
// SEE https://hardhat.org/tutorial/testing-contracts.html
// FOR HELP WRITING TESTS
// USE https://github.com/gnosis/mock-contract FOR HELP
// WITH MOCK CONTRACT
///////////////////////////////////////////////////////////

// Start test block
describe('Coin', function () {
    before(async function () {
        this.Coin = await ethers.getContractFactory("ExampleERC20");
        this.MockContract = await ethers.getContractFactory("contracts/MockContract.sol:MockContract");
    });

    beforeEach(async function () {
        this.coin = await this.Coin.deploy()
        await this.coin.deployed()
        this.mock = await this.MockContract.deploy()
        await this.mock.deployed()
    });

    // Test cases

    //////////////////////////////
    //       Constructor 
    //////////////////////////////
    describe("Constructor", function () {
        it('mock test', async function () {
            // If another contract calls balanceOf on the mock contract, return AMT
            const balanceOf = Web3.utils.sha3('balanceOf(address)').slice(0,10);
            await this.mock.givenMethodReturnUint(balanceOf, AMT);
        });
    });

    //////////////////////////////
    //  setRemainderDestination 
    //////////////////////////////
    describe("otherMethod", function () {

    });
});

================================================
FILE: tsconfig.json
================================================
{
  "compilerOptions": {
    "resolveJsonModule": true
  }
}
Download .txt
gitextract_1nu2uio7/

├── .gitignore
├── LICENSE
├── README.md
├── contracts/
│   ├── ExampleERC20.sol
│   ├── MockContract.sol
│   ├── NFT.sol
│   └── Storage.sol
├── hardhat.config.ts
├── package.json
├── scripts/
│   ├── deploy.ts
│   ├── erc20.ts
│   ├── example.js
│   ├── fund-cchain-addresses.js
│   ├── nft.ts
│   ├── sendAvaxJSONProvider.ts
│   ├── sendAvaxWalletSigner.ts
│   └── storage.ts
├── setup.js
├── test/
│   └── Coin.js
└── tsconfig.json
Download .txt
SYMBOL INDEX (10 symbols across 4 files)

FILE: hardhat.config.ts
  constant FORK_FUJI (line 12) | const FORK_FUJI = false
  constant FORK_MAINNET (line 13) | const FORK_MAINNET = false

FILE: scripts/example.js
  constant COIN_ADDR (line 5) | const COIN_ADDR = "0x0000000000000000000000000000000000000000";
  function main (line 10) | async function main() {
  function calculateGasFee (line 21) | async function calculateGasFee(tx, methodName) {
  function sendERC20 (line 41) | async function sendERC20(from, to, amount, coinContract) {

FILE: scripts/sendAvaxJSONProvider.ts
  type Param (line 3) | interface Param {

FILE: test/Coin.js
  constant OWNER_ADDRESS (line 8) | const OWNER_ADDRESS = ethers.utils.getAddress("0xf39Fd6e51aad88F6F4ce6aB...
  constant DECIMALS (line 10) | const DECIMALS = 2;
  constant AMT (line 12) | const AMT = 150
Condensed preview — 20 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (45K chars).
[
  {
    "path": ".gitignore",
    "chars": 2069,
    "preview": "/dist\n\n/.idea\n*.tsbuildinfo\n\n.DS_Store\n\n# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n\nnode_modules/\n"
  },
  {
    "path": "LICENSE",
    "chars": 1522,
    "preview": "BSD 3-Clause License\n\nCopyright (c) 2020, Ava Labs, Inc.\nAll rights reserved.\n\nRedistribution and use in source and bina"
  },
  {
    "path": "README.md",
    "chars": 3291,
    "preview": "## Introduction\n\nAvalanche is an open-source platform for launching decentralized applications and enterprise blockchain"
  },
  {
    "path": "contracts/ExampleERC20.sol",
    "chars": 635,
    "preview": "//SPDX-License-Identifier: MIT\npragma solidity >=0.6.2;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport "
  },
  {
    "path": "contracts/MockContract.sol",
    "chars": 14263,
    "preview": "//SPDX-License-Identifier: MIT\npragma solidity ^0.6.4;\n\n///////////////////////////////////////////////\n// This contract"
  },
  {
    "path": "contracts/NFT.sol",
    "chars": 690,
    "preview": "//SPDX-License-Identifier: MIT\n// contracts/ERC721.sol\n\npragma solidity >=0.6.2;\n\nimport \"@openzeppelin/contracts/token/"
  },
  {
    "path": "contracts/Storage.sol",
    "chars": 243,
    "preview": "//SPDX-License-Identifier: MIT\npragma solidity >=0.6.0 <0.8.0;\n\ncontract Storage {\n  uint256 number;\n\n  function store(u"
  },
  {
    "path": "hardhat.config.ts",
    "chars": 3163,
    "preview": "import { task } from \"hardhat/config\"\nimport { SignerWithAddress } from \"@nomiclabs/hardhat-ethers/signers\"\nimport { Big"
  },
  {
    "path": "package.json",
    "chars": 1747,
    "preview": "{\n  \"name\": \"avalanche-smart-contract-quickstart\",\n  \"devDependencies\": {\n    \"@nomiclabs/hardhat-ethers\": \"^2.0.2\",\n   "
  },
  {
    "path": "scripts/deploy.ts",
    "chars": 434,
    "preview": "import { \n  Contract, \n  ContractFactory \n} from \"ethers\"\nimport { ethers } from \"hardhat\"\n\nconst main = async(): Promis"
  },
  {
    "path": "scripts/erc20.ts",
    "chars": 1583,
    "preview": "import {\n  BigNumber,\n  Contract\n} from \"ethers\"\nimport { ethers } from \"hardhat\"\n\nconst coinName: string = \"\"\nconst coi"
  },
  {
    "path": "scripts/example.js",
    "chars": 1660,
    "preview": "const { Contract } = require(\"ethers\");\nconst hre = require(\"hardhat\");\n\n// TODO: Enter your deployed contract address\nc"
  },
  {
    "path": "scripts/fund-cchain-addresses.js",
    "chars": 6287,
    "preview": "'use strict';\nObject.defineProperty(exports, '__esModule', { value: true });\nconst avalanche_1 = require('avalanche');\nc"
  },
  {
    "path": "scripts/nft.ts",
    "chars": 531,
    "preview": "import { Contract } from \"ethers\"\nimport { ethers } from \"hardhat\"\nimport { abi } from \"../artifacts/contracts/NFT.sol/N"
  },
  {
    "path": "scripts/sendAvaxJSONProvider.ts",
    "chars": 651,
    "preview": "import { utils } from \"ethers\"\nimport { ethers } from \"hardhat\"\ninterface Param {\n  from: string\n  to: string \n  value: "
  },
  {
    "path": "scripts/sendAvaxWalletSigner.ts",
    "chars": 1104,
    "preview": "import { \n  BigNumber,\n  providers,\n  utils,\n  Wallet\n} from \"ethers\"\n\nconst walletAddress: string = \"0xDd1749831fbF70d8"
  },
  {
    "path": "scripts/storage.ts",
    "chars": 488,
    "preview": "import { \n  BigNumber,\n  Contract\n} from \"ethers\"\nimport { ethers } from \"hardhat\"\n\nconst contractName: string = \"Storag"
  },
  {
    "path": "setup.js",
    "chars": 64,
    "preview": "const hardhat = require(\"hardhat\")\nconst Web3 = require(\"web3\")\n"
  },
  {
    "path": "test/Coin.js",
    "chars": 1690,
    "preview": "// test/Airdrop.js\n// Load dependencies\nconst { expect } = require('chai');\nconst { BigNumber } = require('ethers');\ncon"
  },
  {
    "path": "tsconfig.json",
    "chars": 60,
    "preview": "{\n  \"compilerOptions\": {\n    \"resolveJsonModule\": true\n  }\n}"
  }
]

About this extraction

This page contains the full source code of the ava-labs/avalanche-smart-contract-quickstart GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 20 files (41.2 KB), approximately 11.8k tokens, and a symbol index with 10 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!