This commit is contained in:
writer 2024-10-15 12:26:21 +09:00
parent c2d0866191
commit db37d209ab
58 changed files with 4663 additions and 1043 deletions

View file

@ -0,0 +1,8 @@
## workspaces
<br>
* **[i use foundry](foundry.md)**
* **[notes on using remix](remix.md)**
* **[a simple intro to hardhat with a `erc721` token](hardhat/)**
* **[old stuff: truffle](https://trufflesuite.com/)**

View file

@ -0,0 +1,31 @@
## foundry and tests in solidity
<br>
### tl; dr
<br>
* **[foundry](https://book.getfoundry.sh/forge/differential-ffi-testing)** is a set of tools for evm-based smart contract development and tests, written in rust.
<br>
---
### resources
<br>
* **[ethernaut solutions systematically on foundry](https://github.com/go-outside-labs/ethernaut-foundry-detailed-solutions-sol)**
* **[go-outside-labs experiments on foundry](https://github.com/go-outside-labs/blockchain-science-rs#experiments-with-foundry)**
* **[how to test smart contracts](https://betterprogramming.pub/how-to-test-ethereum-smart-contracts-35abc8fa199d)**
* **[how to mock solidity contracts](https://ethereum.org/en/developers/tutorials/how-to-mock-solidity-contracts-for-testing/)**
* **[in-depth guide to testing ethereum smart contracts](https://iamdefinitelyahuman.medium.com/an-in-depth-guide-to-testing-ethereum-smart-contracts-2e41b2770297)**

View file

@ -0,0 +1,5 @@
API_URL = "https://eth-rinkeby.alchemyapi.io/v2/<project>"
PUBLIC_KEY =
PRIVATE_KEY =
METADATA_URL = <pinata IPFS cid dor metadata>"
CONTRACT_ADDRESS =

View file

@ -0,0 +1,25 @@
## get started with hardhat + erc721
<br>
1. compile contract:
```
npx hardhat compile
```
<br>
2. deploy contract:
```
npx hardhat run scripts/deploy-contract.js --network rinkeby
```
<br>
3. mint NFT:
```
node scripts/mint-nft.js
```

View file

@ -0,0 +1,28 @@
// SPDX-License-Identifier: MIT
pragma solidity >=0.7.3 <0.9.0;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
contract MiaNFT is ERC721, Ownable {
using Counters for Counters.Counter;
Counters.Counter private _tokenIds;
constructor() public ERC721("Mia's NFT, "NFT") {}
function mintNFT(address recipient, string memory tokenURI)
public onlyOwner
returns (uint256)
{
_tokenIds.increment();
uint256 newItemId = _tokenIds.current();
_mint(recipient, newItemId);
_setTokenURI(newItemId, tokenURI);
return newItemId;
}
}

View file

@ -0,0 +1,19 @@
/**
* @type import('hardhat/config').HardhatUserConfig
*/
require('dotenv').config();
require("@nomiclabs/hardhat-ethers");
const { API_URL, PRIVATE_KEY } = process.env;
module.exports = {
solidity: "0.7.3",
defaultNetwork: "rinkeby",
networks: {
hardhat: {},
rinkeby: {
url: API_URL,
accounts: [`0x${PRIVATE_KEY}`]
}
},
}

View file

@ -0,0 +1,23 @@
{
"name": "MiaNFT",
"version": "1.0.0",
"description": "",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Mia Stein",
"license": "MIT",
"devDependencies": {
"@nomiclabs/hardhat-ethers": "^2.0.2",
"@nomiclabs/hardhat-waffle": "^2.0.1",
"@openzeppelin/contracts": "^3.1.0-solc-0.7",
"chai": "^4.3.4",
"ethereum-waffle": "^3.4.0",
"ethers": "^5.4.6",
"hardhat": "^2.6.2"
},
"dependencies": {
"@alch/alchemy-web3": "^1.1.4",
"dotenv": "^10.0.0"
}
}

View file

@ -0,0 +1,14 @@
async function main() {
const nft = await ethers.getContractFactory("MiaNFT");
const nft_deploy = await nft.deploy();
console.log(" ⛓🧱✨ Contract address:", nft_deploy.address);
console.log(" ➡️ (Please add this string to .env)");
}
main()
.then(() => process.exit(0))
.catch(e => {
console.error(e);
process.exit(1);
});

View file

@ -0,0 +1,41 @@
require('dotenv').config();
const PUBLIC_KEY = process.env.PUBLIC_KEY;
const PRIVATE_KEY = process.env.PRIVATE_KEY;
const API_URL = process.env.API_URL;
const METADATA_URL = process.env.METADATA_URL;
const CONTRACT_ADDRESS = process.env.CONTRACT_ADDRESS;
const { createAlchemyWeb3 } = require("@alch/alchemy-web3");
const web3 = createAlchemyWeb3(API_URL);
const contract = require("../artifacts/contracts/MiaNFT.sol/MiaNFT.json");
const nftContract = new web3.eth.Contract(contract.abi, CONTRACT_ADDRESS);
async function mintNFT(tokenURI) {
const nonce = await web3.eth.getTransactionCount(PUBLIC_KEY, 'latest');
const transaction = {
'from': PUBLIC_KEY,
'to': CONTRACT_ADDRESS,
'nonce': nonce,
'gas': 500000,
'maxPriorityFeePerGas': 1999999987,
'data': nftContract.methods.mintNFT(PUBLIC_KEY, tokenURI).encodeABI()
};
const sign = web3.eth.accounts.signTransaction(transaction, PRIVATE_KEY);
sign.then((signedTransaction) => {
web3.eth.sendSignedTransaction(signedTransaction.rawTransaction, function(e, hash) {
if (!e) {
console.log("💾 Transaction hash: ", hash);
} else {
console.log("ERROR:", e)
}
});
}).catch((e) => {
console.log("ERROR:", e);
});
}
mintNFT(METADATA_URL);

View file

@ -0,0 +1,68 @@
## remix IDE
<br>
* remix IDE is an open source web3 application and it's used for the entire journey of smart contract development.
<br>
<img width="414" alt="Screen Shot 2022-03-10 at 5 57 22 PM" src="https://user-images.githubusercontent.com/1130416/157715032-63dfbe5d-292d-48e3-8594-04902fb008f6.png">
<br>
* everything in Remix is a plugin. the plugin mamanger is the place to load functionalities and create your own plugins.
* by default, Remix stores files in workspaces, which are folders in the browser's local storage.
* you can publish all files from current workspace to a gist, using the gist API.
<br>
#### compiler (Solidity)
* you can compile (and deploy) contracts with versions of Solidity older than 0.4.12. however, the older compilers used a legacy AST.
* the "fork selection" dropdown list allows to compile code against a specific ehtereum hard fork.
<br>
#### optimization
* the optimizer tries to simplify complicated expressions, which reduces both code size and execution cost. It can reduce gas needed for contract deployment as well as for external calls made to the contract.
<br>
#### environment
* `JavaScript VM`: All transactions will be executed in a sandbox blockchain in the browser.
* `Injected Provider`: Metamaask is an example of a profiver that inject web3.
* `Web3 Provider`: Remix will connect to a remote node (you need to provide the URL to the selected provider: geth, parity or any ethereum client)
<br>
#### setup
* gas Limit: sets the amount of `ETH`, `WEI`, `GWEI` that is sent to ta contract or a payable function.
* deploy: sends a transaction that deplpys the selected contract.
* `atAdress`: used to access a contract whtat has already been deployed (does not cost gas).
* to interact with a contract using the ABI, create a new file in remix, with extension `.abi`.
* the Recorder is a tool used to save a bunch of transactions in a `json` file and rerun them later either in the same environment or in another.
* the Debugger shows the contract's state while stepping through a transaction.
* using generated sources will make it easier to audit your contracts.
* dtatic code analysis can be done by a plugin, so that you can examine the code for security vulnerabilities, bad development practices, etc.
* hardhat integration can be done with `hardhat.config.js` (Hardhat websocket listener should run at `65522`). hardhat provider is a plugin for Rrmix IDE.
<br>
#### generate artifacts
* when a compilation for a Solidity file succeeds, remix creates three `json` files for each compiled contract, that can be seen in the `File Explorers plugin`:
1. `artifacts/<contractName>.json`: contains links to libraries, the bytecode, gas estimation, the ABI.
2. `articfacts/<contractName_metadata>.json`: contains the metadata from the output of Solidity compilation.
3. `artifcats/build-info/<dynamic_hash>.json`: contains info about `solc` compiler version, compiler input and output.