├── .gitignore ├── truffle-box.json ├── migrations └── 1_deploy_simple_storage.js ├── contracts ├── ethereum │ └── SimpleStorage.sol └── polygon │ └── SimpleStorage.sol ├── test └── simplestorage.js ├── package.json ├── truffle-config.polygon.js ├── truffle-config.js └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .env 2 | .env.test 3 | build 4 | node_modules 5 | -------------------------------------------------------------------------------- /truffle-box.json: -------------------------------------------------------------------------------- 1 | { 2 | "commands": { 3 | "Compile Contracts": "truffle compile" 4 | }, 5 | "hooks": { 6 | "post-unpack": "npm install" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /migrations/1_deploy_simple_storage.js: -------------------------------------------------------------------------------- 1 | const SimpleStorage = artifacts.require("SimpleStorage"); 2 | 3 | module.exports = function (deployer) { 4 | deployer.deploy(SimpleStorage); 5 | }; 6 | -------------------------------------------------------------------------------- /contracts/ethereum/SimpleStorage.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity >=0.4.21 <0.7.0; 3 | 4 | contract SimpleStorage { 5 | uint storedData; 6 | 7 | function set(uint x) public { 8 | storedData = x; 9 | } 10 | 11 | function get() public view returns (uint) { 12 | return storedData; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /contracts/polygon/SimpleStorage.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity >=0.4.21 <0.7.0; 3 | 4 | contract SimpleStorage { 5 | uint storedData; 6 | 7 | function set(uint x) public { 8 | storedData = x; 9 | } 10 | 11 | function get() public view returns (uint) { 12 | return storedData; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /test/simplestorage.js: -------------------------------------------------------------------------------- 1 | const SimpleStorage = artifacts.require("./SimpleStorage.sol"); 2 | 3 | contract("SimpleStorage", accounts => { 4 | it("...should store the value 89.", async () => { 5 | const simpleStorageInstance = await SimpleStorage.deployed(); 6 | 7 | // Set value of 89 8 | await simpleStorageInstance.set(89, { from: accounts[0] }); 9 | 10 | // Get stored value 11 | const storedData = await simpleStorageInstance.get.call(); 12 | 13 | assert.equal(storedData, 89, "The value 89 was not stored."); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "polygon-box", 3 | "version": "1.0.0", 4 | "description": "A sample Truffle project that allows developers to deploy to the Polygon Matic PoS chain", 5 | "main": "truffle-config.js", 6 | "directories": { 7 | "test": "test" 8 | }, 9 | "scripts": { 10 | "test": "truffle test", 11 | "test:polygon": "truffle test --config=truffle-config.polygon.js --network=$npm_config_network", 12 | "compile:polygon": "truffle compile --config=truffle-config.polygon.js", 13 | "migrate:polygon": "truffle migrate --config=truffle-config.polygon.js --network=$npm_config_network" 14 | }, 15 | "repository": { 16 | "type": "git", 17 | "url": "git+https://github.com/truffle-box/polygon-box.git" 18 | }, 19 | "keywords": [ 20 | "Matic", 21 | "Polygon", 22 | "Ethereum", 23 | "Truffle", 24 | "dapp" 25 | ], 26 | "author": "Faina Shalts", 27 | "license": "MIT", 28 | "bugs": { 29 | "url": "https://github.com/truffle-box/polygon-box/issues" 30 | }, 31 | "homepage": "https://github.com/truffle-box/polygon-box#readme", 32 | "devDependencies": { 33 | "@maticnetwork/maticjs": "^2.0.40", 34 | "@truffle/hdwallet-provider": "^1.4.2", 35 | "dotenv": "^9.0.0" 36 | }, 37 | "dependencies": {} 38 | } 39 | -------------------------------------------------------------------------------- /truffle-config.polygon.js: -------------------------------------------------------------------------------- 1 | const HDWalletProvider = require('@truffle/hdwallet-provider'); 2 | // create a file at the root of your project and name it .env -- there you can set process variables 3 | // like the mnemomic and Infura project key below. Note: .env is ignored by git to keep your private information safe 4 | require('dotenv').config(); 5 | const mnemonic = process.env["MNEMONIC"]; 6 | const infuraProjectId = process.env["INFURA_PROJECT_ID"]; 7 | 8 | module.exports = { 9 | 10 | /** 11 | * contracts_build_directory tells Truffle where to store compiled contracts 12 | */ 13 | contracts_build_directory: './build/polygon-contracts', 14 | 15 | /** 16 | * contracts_directory tells Truffle where the contracts you want to compile are located 17 | */ 18 | contracts_directory: './contracts/polygon', 19 | 20 | 21 | networks: { 22 | development: { 23 | host: "127.0.0.1", // Localhost (default: none) 24 | port: 8545, // Standard Ethereum port (default: none) 25 | network_id: "*", // Any network (default: none) 26 | }, 27 | //polygon Infura mainnet 28 | polygon_infura_mainnet: { 29 | provider: () => new HDWalletProvider({ 30 | mnemonic: { 31 | phrase: mnemonic 32 | }, 33 | providerOrUrl: 34 | "https://polygon-mainnet.infura.io/v3/" + infuraProjectId 35 | }), 36 | network_id: 137, 37 | confirmations: 2, 38 | timeoutBlocks: 200, 39 | skipDryRun: true, 40 | chainId: 137 41 | }, 42 | //polygon Infura testnet 43 | polygon_infura_testnet: { 44 | provider: () => new HDWalletProvider({ 45 | mnemonic: { 46 | phrase: mnemonic 47 | }, 48 | providerOrUrl: 49 | "https://polygon-mumbai.infura.io/v3/" + infuraProjectId 50 | }), 51 | network_id: 80001, 52 | confirmations: 2, 53 | timeoutBlocks: 200, 54 | skipDryRun: true, 55 | chainId: 80001 56 | } 57 | }, 58 | 59 | // Set default mocha options here, use special reporters etc. 60 | mocha: { 61 | // timeout: 100000 62 | }, 63 | 64 | // Configure your compilers 65 | compilers: { 66 | solc: { 67 | } 68 | }, 69 | db: { 70 | enabled: true 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /truffle-config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Use this file to configure your truffle project. It's seeded with some 3 | * common settings for different networks and features like migrations, 4 | * compilation and testing. Uncomment the ones you need or modify 5 | * them to suit your project as necessary. 6 | * 7 | * More information about configuration can be found at: 8 | * 9 | * trufflesuite.com/docs/advanced/configuration 10 | * 11 | * To deploy via Infura you'll need a wallet provider (like @truffle/hdwallet-provider) 12 | * to sign your transactions before they're sent to a remote public node. Infura accounts 13 | * are available for free at: infura.io/register. 14 | * 15 | * You'll also need a mnemonic - the twelve word phrase the wallet uses to generate 16 | * public/private key pairs. If you're publishing your code to GitHub make sure you load this 17 | * phrase from a file you've .gitignored so it doesn't accidentally become public. 18 | * 19 | */ 20 | 21 | // const HDWalletProvider = require('@truffle/hdwallet-provider'); 22 | // const infuraKey = "fj4jll3k....."; 23 | // 24 | // const fs = require('fs'); 25 | // const mnemonic = fs.readFileSync(".secret").toString().trim(); 26 | 27 | module.exports = { /** 28 | 29 | * contracts_build_directory tells Truffle where to store compiled contracts 30 | */ 31 | contracts_build_directory: './build/ethereum-contracts', 32 | 33 | /** 34 | * contracts_directory tells Truffle where the contracts you want to compile are located 35 | */ 36 | contracts_directory: './contracts/ethereum', 37 | 38 | /** 39 | * Networks define how you connect to your ethereum client and let you set the 40 | * defaults web3 uses to send transactions. If you don't specify one truffle 41 | * will spin up a development blockchain for you on port 9545 when you 42 | * run `develop` or `test`. You can ask a truffle command to use a specific 43 | * network from the command line, e.g 44 | * 45 | * $ truffle test --network 46 | */ 47 | 48 | networks: { 49 | development: { 50 | host: "127.0.0.1", // Localhost (default: none) 51 | port: 8545, // Standard Ethereum port (default: none) 52 | network_id: "*", // Any network (default: none) 53 | } 54 | }, 55 | 56 | // Set default mocha options here, use special reporters etc. 57 | mocha: { 58 | // timeout: 100000 59 | }, 60 | 61 | // Configure your compilers 62 | compilers: { 63 | solc: { 64 | // version: "0.5.1", // Fetch exact version from solc-bin (default: truffle's version) 65 | // docker: true, // Use "0.5.1" you've installed locally with docker (default: false) 66 | // settings: { // See the solidity docs for advice about optimization and evmVersion 67 | // optimizer: { 68 | // enabled: false, 69 | // runs: 200 70 | // }, 71 | // evmVersion: "byzantium" 72 | // } 73 | } 74 | }, 75 | 76 | // Truffle DB is enabled in this project by default. Enabling Truffle DB surfaces access to the @truffle/db package 77 | // for querying data about the contracts, deployments, and networks in this project 78 | db: { 79 | enabled: true 80 | } 81 | }; 82 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Polygon Box 2 | 3 | - [Requirements](#requirements) 4 | - [Installation](#installation) 5 | - [Setup](#setup) 6 | - [Using the .env File](#using-the-env-file) 7 | - [New Configuration File](#new-configuration-file) 8 | - [New Directory Structure for Artifacts](#new-directory-structure-for-artifacts) 9 | - [Polygon PoS Chain](#polygon-pos-chain) 10 | - [Compiling](#compiling) 11 | - [Migrating](#migrating) 12 | - [Paying For Migrations](#paying-for-migrations) 13 | - [Basic Commands](#basic-commands) 14 | - [Testing](#testing) 15 | - [Communication Between Ethereum and Polygon PoS Chains](#communication-between-ethereum-and-polygon-pos-chains) 16 | - [Support](#support) 17 | 18 | Table of contents generated with markdown-toc 19 | 20 | This Truffle Polygon box provides you with the boilerplate structure necessary to start coding for Polygon's Ethereum L2 solution, the Polygon PoS chain (previously called the Matic PoS chain). For detailed information on how the Polygon PoS chain works, please see their documentation [here](https://docs.matic.network/docs/develop/getting-started). 21 | 22 | As a starting point, this box contains only the SimpleStorage Solidity contract. Including minimal code was a conscious decision as this box is meant to provide the initial building blocks needed to get to work on Polygon PoS without pushing developers to write any particular sort of application. With this box, you will be able to compile, migrate, and test Solidity code against several instances of Polygon PoS networks. 23 | 24 | Polygon's L2 solution is fully compatible with the EVM. This means you will not need a new compiler to deploy Solidity contracts, and should be able to add your own Solidity contracts to this project. The main difference developers will encounter is in accessing and interacting with the Polygon PoS network. Additionally, Polygon offers multiple ways for dapp developers to implement communication between Ethereum ("Layer 1") and Polygon PoS. Further information about how to enable Ethereum-Polygon communication can be found in the Polygon documentation [here](https://docs.matic.network/docs/develop/ethereum-matic/getting-started). 25 | 26 | _A note about naming: The Polygon ecosystem was previously called Matic Network. The chain to which we'll be deploying in this Truffle Box is now called the Polygon PoS chain. We have named this box the Polygon Box because we expect to include the ability to deploy to future Polygon chains in addition to what is presented here as an initial proof-of-concept, and developers using this Polygon Box may find themselves incorporating additional aspects of the Polygon ecosystem in their work._ 27 | 28 | ## Requirements 29 | 30 | The Polygon box has the following requirements: 31 | 32 | - [Node.js](https://nodejs.org/) 10.x or later 33 | - [NPM](https://docs.npmjs.com/cli/) version 5.2 or later 34 | - Windows, Linux or MacOS 35 | 36 | Helpful, but optional: 37 | 38 | - An [Infura](https://infura.io/) account and Project ID 39 | - A [MetaMask](https://metamask.io/) account 40 | 41 | ## Installation 42 | 43 | ```bash 44 | $ truffle unbox polygon 45 | ``` 46 | 47 | ## Setup 48 | 49 | ### Using the env File 50 | 51 | You will need at least one mnemonic to use with the network. The `.dotenv` npm package has been installed for you, and you will need to create a `.env` file for storing your mnemonic and any other needed private information. 52 | 53 | The `.env` file is ignored by git in this project, to help protect your private data. In general, it is good security practice to avoid committing information about your private keys to github. The `truffle-config.polygon.js` file expects a `MNEMONIC` value to exist in `.env` for running migrations on the networks listed in `truffle-config.polygon.js`. 54 | 55 | If you are unfamiliar with using `.env` for managing your mnemonics and other keys, the basic steps for doing so are below: 56 | 57 | 1. Use `touch .env` in the command line to create a `.env` file at the root of your project. 58 | 2. Open the `.env` file in your preferred IDE 59 | 3. Add the following, filling in your own mnemonic and Infura project key: 60 | 61 | ``` 62 | MNEMONIC="" 63 | INFURA_PROJECT_ID="" 64 | ``` 65 | 66 | 4. As you develop your project, you can put any other sensitive information in this file. You can access it from other files with `require('dotenv').config()` and refer to the variable you need with `process.env['']`. 67 | 68 | ### New Configuration File 69 | 70 | A new configuration file exists in this project: `truffle-config.polygon.js`. This file contains a reference to the new file location of the `contracts_build_directory` for Polygon PoS contracts and lists several networks that are running the Polygon PoS Layer 2 network instance (see [below](#migrating)). 71 | 72 | Please note, the classic `truffle-config.js` configuration file is included here as well, because you will eventually want to deploy contracts to Ethereum as well. All normal truffle commands (`truffle compile`, `truffle migrate`, etc.) will use this config file and save built files to `build/ethereum-contracts`. You can save Solidity contracts that you wish to deploy to Ethereum in the `contracts/ethereum` folder. 73 | 74 | ### New Directory Structure for Artifacts 75 | 76 | When you compile or migrate, the resulting `json` files will be at `build/polygon-contracts/`. This is to distinguish them from any Ethereum contracts you build, which will live in `build/ethereum-contracts `. As we have included the appropriate `contracts_build_directory` in each configuration file, Truffle will know which set of built files to reference! 77 | 78 | ## Polygon PoS Chain 79 | 80 | ### Compiling 81 | 82 | You do not need to add any new compilers or settings to compile your contracts for the Polygon PoS chain, as it is fully EVM compatible. The `truffle-config.polygon.js` configuration file indicates the contract and build paths for Polygon-destined contracts. 83 | 84 | If you are compiling contracts specifically for the Polygon PoS network, use the following command, which indicates the appropriate configuration file: 85 | 86 | ``` 87 | npm run compile:polygon 88 | ``` 89 | 90 | If you would like to recompile previously compiled contracts, you can manually run this command with 91 | `truffle compile --config=truffle-config.polygon.js` and add the `--all` flag. 92 | 93 | ### Migrating 94 | 95 | To migrate on the Polygon PoS network, run `npm run migrate:polygon --network=(polygon_infura_testnet | polygon_infura_mainnet)` (remember to choose a network from these options!). 96 | 97 | As you can see, you have several Polygon PoS L2 networks to choose from: 98 | 99 | _Infura networks_. Infura is running a testnet node as well as a mainnet node for the Polygon PoS chain. Deployment to these networks requires that you sign up for an Infura account and initiate a project. See the Infura website for [details](https://infura.io/). In the example network configuration, we expect you to have a public Infura project key, which you should indicate in your `.env` file. The following Infura networks are indicated in the `truffle-config.polygon.js` file: 100 | 101 | - `polygon_infura_testnet`: This is the Infura Polygon PoS testnet. 102 | - `polygon_infura_mainnet`: This is the Infura Polygon PoS mainnet. Caution! If you deploy to this network using a connected wallet, the fees are charged in mainnet MATIC. 103 | 104 | If you would like to migrate previously migrated contracts on the same network, you can run `truffle migrate --config truffle-config.polygon.js --network= (polygon_infura_testnet | polygon_infura_mainnet)` and add the `--reset` flag. 105 | 106 | ### Paying for Migrations 107 | 108 | To pay for your deployments, you will need to have an account with ETH available to spend. You will need your mnemomic phrase (saved in the `.env` file or through some other secure method). The first account generated by the seed needs to have the ETH you need to deploy. For reference, the Polygon PoS testnets are based in goerli, so you should be able to use goerli ETH. 109 | 110 | If you do not have a wallet with funds to deploy, you will need to connect a wallet to at least one of the networks above. For testing, this means you will want to connect a wallet to the `polygon_infura_testnet` network. We recommend using [MetaMask](https://metamask.io/). 111 | 112 | Documentation for how to set up MetaMask custom networks with the Polygon PoS network can be found [here](https://docs.matic.network/docs/develop/metamask/config-matic). 113 | 114 | Follow the steps in the documentation above using Infura's RPC endpoints (`"https://polygon-mainnet.infura.io/v3/" + infuraProjectId` and `"https://polygon-mumbai.infura.io/v3/" + infuraProjectId`). The `chainId` values are the same as those in the `truffle-config.polygon.js` networks entries. 115 | 116 | To get testnet ETH to use, visit a faucet like https://goerli-faucet.slock.it/. 117 | 118 | ## Basic Commands 119 | 120 | The code here will allow you to compile, migrate, and test your code against a Polygon PoS network instance. The following commands can be run (more details on each can be found in the next section): 121 | 122 | To compile: 123 | 124 | ``` 125 | npm run compile:polygon 126 | ``` 127 | 128 | To migrate: 129 | 130 | ``` 131 | npm run migrate:polygon --network=(polygon_infura_testnet | polygon_infura_mainnet) 132 | ``` 133 | 134 | To test: 135 | 136 | ``` 137 | npm run test:polygon --network=(polygon_infura_testnet | polygon_infura_mainnet) 138 | ``` 139 | 140 | ### Testing 141 | 142 | In order to run the test currently in the boilerplate, use the following command: `npm run test:polygon --network=(polygon_infura_testnet | polygon_infura_mainnet)` (remember to choose a network!). The current test file just has some boilerplate tests to get you started. You will likely want to add network-specific tests to ensure your contracts are behaving as expected. 143 | 144 | ### Communication Between Ethereum and Polygon PoS Chains 145 | 146 | The information above should allow you to deploy to the Polygon PoS Layer 2 chain. This is only the first step! Once you are ready to deploy your own contracts to function on L1 using L2, you will need to be aware of the [ways in which Layer 1 and Layer 2 interact in the Polygon ecosystem](https://docs.matic.network/docs/develop/ethereum-matic/getting-started). Keep an eye out for additional Truffle tooling and examples that elucidate this second step to full Polygon PoS L2 integration! 147 | 148 | ## Support 149 | 150 | Support for this box is available via the Truffle community [here](https://www.trufflesuite.com/community). 151 | --------------------------------------------------------------------------------