# Nero 實習 (vera)
<!-- https://www.figma.com/file/D8rVMIMO791hg0XYiVHKBv/Nero-UI?type=design&node-id=0-1&mode=design -->
<!-- 任務連結:https://hackmd.io/@zinstitute/HktIQ3yH2 -->
### [套件安裝](https://docs.blockscout.com/for-developers/information-and-settings/requirements)
```
brew install erlang
brew install elixir
brew install postgresql
brew install node
brew install automake
brew install libtool
brew install gcc
brew install gmp
```
--
### [Docker setup](https://docs.blockscout.com/for-developers/information-and-settings/docker-integration-local-use-only)
安裝 m2 的 [docker 環境](https://yeasy.gitbook.io/docker_practice/install/mac)
--
terminal 1:
run 本機的 geth

terminal 2:
```
docker-compose up --build
```
他會卡在 build 階段

把 alpine-elixir-phoenix:1.14 版本降下來變成 1.13,有順利解決 139 的錯誤訊息
```
// 有兩處都要改成 1.13
FROM bitwalker/alpine-elixir-phoenix:1.13
```
錯誤訊息變成無法 install

package-lock.json 刪除重新 build( block_scout_web / explorer 裡面的 )

build 成功,但裡面目前沒東西
```
http://localhost:4000/
```

--
0611:本機目前 run 不起來,問題同下
https://github.com/blockscout/blockscout/issues/7549
--
注意事項:
1. docker 裡面的 Use Rosetta for x86/amd64 emulation on Apple Silicon 選項要勾起來。
2. mac m1 / m2 是屬於 arm64 晶片,設定上要注意
--
### [OP Stack and Celestia tutorial](https://docs.celestia.org/developers/optimism/)
#### Environment setup and Golang installation
Install wget and jq
```
brew install wget && brew install jq
```
Install Golang
```
ver="1.20.2"
cd $HOME
wget "https://golang.org/dl/go$ver.darwin-amd64.tar.gz"
sudo rm -rf /usr/local/go
sudo tar -C /usr/local -xzf "go$ver.darwin-amd64.tar.gz"
rm "go$ver.darwin-amd64.tar.gz"
```
Now we need to add the /usr/local/go/bin directory to $PATH:
```
echo "export PATH=$PATH:/usr/local/go/bin:$HOME/go/bin" >> $HOME/.bash_profile
source $HOME/.bash_profile
```
確認安裝成功
```
go version
```
--
#### Clone repository
```
cd $HOME
git clone https://github.com/celestiaorg/optimism
cd optimism
git checkout celestia-develop
```
### asdf
<!-- 打開新的terminal -->
```
cd $HOME
git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch v0.11.2
echo '. "$HOME/.asdf/asdf.sh"' >> ~/.bashrc
echo '. "$HOME/.asdf/completions/asdf.bash"' >> ~/.bashrc
```
--
Set the path:
```
export PATH=$PATH:~/.asdf/bin/
```
確認安裝
```
asdf
```
Install nodejs 16.16.0:
```
asdf plugin add nodejs
asdf install nodejs 16.16.0
asdf local nodejs 16.16.0
source ~/.bashrc
curl -L https://foundry.paradigm.xyz/ | bash
source /Users/vera/.zshenv
foundryup
```
#### Build devnet
```
cd $HOME
cd optimism
make build-ts
export SEQUENCER_BATCH_INBOX_ADDRESS=0xff00000000000000000000000000000000000000
export L2OO_ADDRESS=0x70997970C51812dc3A010C7d01b50e0d17dc79C8
```
--
### Start devnet
```
make devnet-up
```

錯誤訊息如下

把已經定義過重複的值隱蔽

成功

--
### Stop devnet
```
make devnet-down
make devnet-clean
```

--
### Viewing containers
當 docker run 起來的時候
```
docker ps
```

--
### Find a transaction
```
cast block latest --rpc-url localhost:8545
```

<!-- =>>> 先做到這裡 --> -->
--
結合任務 1 / 2,成功

<!-- --
調整的參數清單
https://docs.blockscout.com/for-developers/information-and-settings/env-variables
-->
--
### 任務三
* [工具](https://www.npmjs.com/package/hardhat-forta)(hardhat plugin)
* 測試時可連接到目前的測試網,並模擬發送交易看看有沒有跳出正確的交易模擬訊息
1. 研究後發現他是監控[交易異常](https://docs.forta.network/en/latest/api-example-use-cases/ )的工具,並非可以偵測交易後 token 的轉變 (與需求不符合)
2. 重新確認需求是希望能<核可交易之後會減少或增加多少 token>,目前還在尋求做法或是範例
* 像是preview的功能嗎 https://github.com/blocknative/web3-onboard
* 還是我要在本機做一個 fork 測試機 rpc,然後發送交易
* 先傳到後端express(node js),先丟到fork去,確認event的值,回傳res帶著0x data,回傳給客戶看資產變化的預測值,他確認後還是要再送一次後端,再上鏈
* 開發api去發送交易,不能用8545可能是8546之類的
先用hardhat做fork,發交易,拿到資訊這段
https://stackoverflow.com/questions/69013697/get-events-from-a-transaction-receipt-in-hardhat
--
## 先用[hardhat](https://hardhat.org/hardhat-runner/docs/getting-started)做fork,發交易,拿到資訊這段
```
創資料夾
cd 資料夾
npm install --save-dev hardhat
npm install --save-dev @nomiclabs/hardhat-ethers ethers
npx hardhat
```
hardhat.config.js
```
require("@nomicfoundation/hardhat-toolbox");
require('@nomiclabs/hardhat-ethers');
/** @type import('hardhat/config').HardhatUserConfig */
module.exports = {
solidity: "0.8.18",
networks: {
hardhat: {
forking: {
url: "http://139.162.97.228:9545"
}
}
}
};
```
--
### 方法1:
創建一個範例的合約 Test.sol
```
// contracts/Box.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Test {
uint256 private _value;
// Emitted when the stored value changes
event ValueChanged(uint256 value);
// Stores a new value in the contract
function store(uint256 value) public {
_value = value;
emit ValueChanged(value);
}
// Reads the last stored value
function retrieve() public view returns (uint256) {
return _value;
}
}
```
deploy.js
```
// scripts/deploy.js
async function main() {
// We get the contract to deploy
const Test = await ethers.getContractFactory('Test');
const test = await Test.deploy();
await test.deployed();
console.log('Test deployed to:', test.address);
}
main()
.then(() => process.exit(0))
.catch(error => {
console.error(error);
process.exit(1);
});
```
terminal1:
```
npx hardhat node
```
terminal2:
```
npx hardhat run --network localhost scripts/deploy.js
npx hardhat console --network localhost
const Test = await ethers.getContractFactory('Test');
const test = await Test.attach('0X........')
await test.store(42) //這你可以嘗試合約內的function
```



--
### 方法2:
<!-- https://ethereum.stackexchange.com/questions/95023/hardhat-how-to-interact-with-a-deployed-contract -->
先部署合約
```
npx hardhat run --network localhost scripts/deploy.js
```
將部署後的 address 帶到下面
( 用 attach / getContractAt 得到結果一樣 )
```
// scripts/call.js
require('@nomiclabs/hardhat-ethers');
const main = async () => {
const contractAddress = "0x3Aa5ebB10DC797CAC828524e59A333d0A371443c"; -> 已部署的合約地址,可用上面方法 deploy
const myContract = await hre.ethers.getContractAt("Test", contractAddress);
console.log(await myContract.store(42))
};
main().catch((error) => {
console.log(error);
process.exit(1);
});
```
terminal1:
```
npx hardhat node
```
terminal2:
```
npx hardhat run scripts/call.js --network localhost
```

0626 更新成:
```
// scripts/call.js
require('@nomiclabs/hardhat-ethers');
const main = async () => {
const Test = await ethers.getContractFactory('Test');
const test = await Test.attach('0xc3e53F4d16Ae77Db1c982e75a937B9f60FE63690');
const transactionResponse = await test.approve('0x90F79bf6EB2c4f870365E785982E1f101E93b906', 100)
const transactionReceipt = await transactionResponse.wait();
if(transactionReceipt.events[0].event == 'Transfer'){
let data = {
function: 'Transfer',
tokenAddress: transactionReceipt.events[0].address,
balance: ethers.utils.formatUnits(transactionReceipt.events[0].args.value, 0),
from: transactionReceipt.events[0].args.from,
to: transactionReceipt.events[0].args.to,
}
console.log(data)
// return data;
}else if(transactionReceipt.events[0].event == 'Approval'){
let data = {
function: 'Approval',
tokenAddress: transactionReceipt.events[0].address,
balance: ethers.utils.formatUnits(transactionReceipt.events[0].args.value, 0),
owner: transactionReceipt.events[0].args.owner,
spender: transactionReceipt.events[0].args.spender,
}
console.log(data)
// return data;
}
};
main().catch((error) => {
console.log(error);
process.exit(1);
});
```
獲得的 console.log

<!-- --
再解析 log
https://youtu.be/ClOATp_GuM4
https://codeburst.io/deep-dive-into-ethereum-logs-a8d2047c7371
-->
--
https://gopluslabs.io/#token_detection
<!-- abi 這欄放我們有興趣的 event 們,例如 Transfer( .. ), Approve( ..) -->
<!--
let abi = [
"event newConnect (string indexed hashedName, string name, bytes32 connectId, string encrypted, address owner)"
];
let iface = new ethers.utils.Interface(abi)
getLogs.then((logs) => {
logs.forEach((log) => {
console.log(iface.parseLog(log));
});
}); -->
<!-- 
```
創建一個 test.js
npx hardhat run scripts/test.js
```

-->
<!-- * https://github.com/EnsoFinance/transaction-simulator
* https://github.com/ethereum/eth-tester
* https://github.com/blocknative/web3-onboard
* https://github.com/hashgraph/hedera-improvement-proposal/discussions/688 -->
--
## [transaction-simulator ](https://github.com/EnsoFinance/transaction-simulator)
安装 rustup
```
curl https://sh.rustup.rs -sSf | sh
source $HOME/.cargo/env 或 export PATH="$HOME/.cargo/bin:$PATH"
```
更新 body.json
```
{
"chainId": 901,
"from": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", -> 需要換成你fork後得到的測試account
"to": "0x7fEA6786D291A87fC4C98aFCCc5A5d3cFC36bc7b",
"data": "0xffa2ca3b44eea7c8e659973cbdf476546e9e6adfd1c580700537e52ba7124933a97904ea000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001d0e30db00300ffffffffffffc02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000186a0",
"gasLimit": 500000,
"value": "100000",
"blockNumber": 1164525,
"formatTrace": true
}
```
copy .env.example to .env, fill out required values and run:
```
cargo run
```
test
> 用於測試api.rs結果是否符合預期expected.json
```
cargo test
```
`body.json` contains a simple request in the root of the project so once the API is running you can just run:
```
$ curl -H "Content-Type: application/json" --data @tests/body.json http://localhost:8080/api/v1/simulate
```
If you have jq installed, you can run this to see pretty traces:
```
$ curl -H "Content-Type: application/json" --data @tests/body.json http://localhost:8080/api/v1/simulate | jq -r ".formattedTrace"
```
--
顯示還未支援該chainId


simulation.rs 裡面新增 chain 901
```
fn chain_id_to_fork_url(chain_id: u64) -> Result<String, Rejection> {
match chain_id {
// nero
901 => Ok("http://139.162.97.228:9545".to_string()),
_ => Err(NoURLForChainIdError.into()),
}
}
```
--
terminal1:
```
cargo run
```
terminal2:
```
$ curl -H "Content-Type: application/json" --data @tests/body.json http://localhost:8080/api/v1/simulate | jq -r ".formattedTrace"
```

--
* Future: Explorer 日文翻譯([教學](https://docs.blockscout.com/for-developers/configuration-options/internationalization))
To setup translation file.
```
cd apps/block_scout_web;
mix gettext.extract --merge;
cd -
```
```
mix deps.update ex_cldr
```
<!--  -->
<!-- Network name: Nero-L1 / Nero-L2
New RPC URL: http://139.162.97.228:8545 / http://139.162.97.228:9545
Chain ID: 900 / 901
Currency symbol: ETH -->