{"id":15907676,"url":"https://github.com/0x-stan/watermargin","last_synced_at":"2026-04-28T20:06:42.833Z","repository":{"id":45228050,"uuid":"441614731","full_name":"0x-stan/WaterMargin","owner":"0x-stan","description":"As a treasure of Chinese literature, 108 heroes in the Water Margin are made into NFT, which is used as a governance tool for the open source community to participate in the better construction of the open source community.","archived":false,"fork":false,"pushed_at":"2021-12-30T05:07:31.000Z","size":4229,"stargazers_count":0,"open_issues_count":0,"forks_count":3,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-08T14:10:00.096Z","etag":null,"topics":["blockchain-oracle","dao","ipfs","nft"],"latest_commit_sha":null,"homepage":"http://81.69.8.95/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/0x-stan.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-12-25T05:59:33.000Z","updated_at":"2021-12-30T05:07:33.000Z","dependencies_parsed_at":"2022-09-02T14:21:45.593Z","dependency_job_id":null,"html_url":"https://github.com/0x-stan/WaterMargin","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0x-stan%2FWaterMargin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0x-stan%2FWaterMargin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0x-stan%2FWaterMargin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/0x-stan%2FWaterMargin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/0x-stan","download_url":"https://codeload.github.com/0x-stan/WaterMargin/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246911495,"owners_count":20853654,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["blockchain-oracle","dao","ipfs","nft"],"created_at":"2024-10-06T14:01:54.383Z","updated_at":"2026-04-28T20:06:42.778Z","avatar_url":"https://github.com/0x-stan.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# WaterMargin\n\nCreate a cyberpunk Water Margin, also an inheritage of Chinese cultural treasures, by combining Web3 technology and traditional culture. An NFT is minted to represent one of the 108 characters of water Margin. Different characters delegate different communal roles of NFT holders. The NFT is integrated with DAO management to motivate members to continuously contribute to open source community.\n\n## white paper\n\n- [WaterMargin DAO white paper](./whitepaper/WaterMargin-DAO-white-paper.pdf)\n- [WaterMargin DAO white paper-cn](./whitepaper/WaterMargin-DAO-white-paper-cn.pdf)\n\n## demo website\n\n- [demo website link](http://81.69.8.95/)\n\n## team members\n\n- Sanhuo (maroonstar): Smart Contract, Frontend Development\n- Hsiang (Hsiang): Smart Contract, Frontend Development\n- Xiath (sansx): The Graph, Frontend Development\n- KellyX (xiepaopaoer): Project Manager, Product Experience Officer\n\n## how to start\n\n- install node_modules\n\n  ```shell\n  cd Dapp-Learning-WaterMargin\n  yarn\n  ```\n\n- config environment\n\n  ```shell\n  cd packages/hardhat\n  cp .env.example .env\n\n  PRIVATE_KEY=xxxxxxxxxxxxxxxx\n  PROJECT_ID=yyyy\n  PROJECT_SECRET=ZZZZ\n  ```\n\n- upload images to IPFS\n\n  ```shell\n  cd Dapp-Learning-WaterMargin\n  yarn upload\n  ```\n\n- set MerkleList  \n  因为 DappLearningCollectible 使用了 Merkle 空投方式, 在部署前需要设置空投的地址, 以便后续进行测试使用.  \n  修改 packages/hardhat/scripts/addressList.json 文件, 在其中设置需要空投的地址\n\n- deploy contract  \n  目前主合约为 DappLearningCollectible, 拍卖合约使用 AuctionFixedPrice.  \n  执行部署命令后, 合约自动部署在 matic 测试网路上, 并发布 ABI 到 react-app/src/contracts 下面. 如果需要部署到其他的测试网路, 需要需改 hardhat/hardhat.config.js 中的 defaultNetwork. packages/hardhat/test/MerkleDrop.test.js 为 Merkle 空投的测试脚本\n\n```shell\ncd Dapp-Learning-WaterMargin\nyarn deploy\n```\n\n- replance WETH address and addressList.json\n  当前竞拍的所使用的标的资产是 ERC20, 为了方便, 同时能适配其他的网络, 需要进行 WETH 地址的替换.  \n  执行如下 replace 命令, 即可替换 react-app/src/contracts/WETH.address.js 中 WETH 的地址, 以及 react-app/src/utils/addressList.json 文件\n\n  ```shell\n  cd Dapp-Learning-WaterMargin\n  yarn replace\n  ```\n\n- deploy subgraph  \n  通过 thegraph 部署的 subgrpah 只能部署在主网 和 rinkeby 网络, 如果需要使用其他的网络, 则需要自己搭建 graph 服务. 下面讲解下如何通过 thegraph 部署 subgraph - 创建 subgraph  \n   在 thegraph 官网上创建一个 subgraph, 假设 subgraph 名字为 DappLearningCollectible\n\n  - install graph-cli\n\n    ```shell\n    yarn global add @graphprotocol/graph-cli\n    ```\n\n  - init subgraph\n\n    ```shell\n    graph init --studio DappLearningCollectible\n\n    ## 在选择网络的时候选择 rinkeby\n    ```\n\n  - subgraph certification\n\n    ```shell\n    graph auth  --studio fc72b2●●●●●●●●476024\n    ```\n\n  - copy and modify config file\n    复制 dapp-learning-test/src/mapping.ts , dapp-learning-test/schema.graphql , dapp-learning-test/subgraph.yaml 到对应的目录下, 同时修改如下配置\n\n    ```shell\n    ## subgraph.yaml 中的 address 和 startBlock\n    source:\n        address: \"0xe1f5CCe0e39E6F3Fec75D29BCb32821A98d8b432\"\n        abi: DappLearningCollectible\n        startBlock: 9737148\n\n    ## mappting.ts 中的 auctionAddr\n    const auctionAddr = Address.fromHexString(\n        \"0xAE8FF5372fE7beb7eBC515ebe19670afd9045bf0\"\n    );\n    ```\n\n  - compile files\n\n    ```shell\n    cd DappLearningCollectible\n    graph codegen \u0026\u0026 graph build\n    ```\n\n  - deploy\n\n    ```shell\n    graph deploy --studio DappLearningCollectible\n    ```\n\n- get graph URL  \n  graph depoloyed, then get info.\n\n  ```shell\n  Subgraph endpoints:\n  Queries (HTTP):     https://api.studio.thegraph.com/query/1542/dapp-learning-test/v0.1.0\n  Subscriptions (WS): https://api.studio.thegraph.com/query/1542/dapp-learning-test/v0.1.0\n  ```\n\n- copy environment variables\n\n  ```shell\n  cd react\n  cp .env.example .env\n\n  ## 然后在其中配置 REACT_APP_PROVIDER 和 REACT_APP_GRAPHQL, 其中 REACT_APP_GRAPHQL 值为上一步 graph 部署成功后显示的值\n  REACT_APP_PROVIDER\n  REACT_APP_GRAPHQL\n  ```\n\n- start react\n\n  ```\n  yarn start\n  ```\n\n- Mint NFT\n  只有在 packages/hardhat/scripts/addressList.json 文件中的账户地址才能进行 Mint 操作.\n\n- 拍卖  \n  查看 Auction 合约中的 createTokenAuction 方法, 即拍卖方法, 可以发现其中调用了 IERC721(\\_nft).safeTransferFrom(owner, address(this), \\_tokenId), 即用户在执行拍卖前需要对 Auction 合约进行 NFT 的 approve 授权\n\n```\nfunction createTokenAuction(\n        address _nft,\n        uint256 _tokenId,\n        address _tokenAddress,\n        uint256 _price,\n        uint256 _duration\n    ) external {\n        require(msg.sender != address(0));\n        require(_nft != address(0));\n        require(_price \u003e 0);\n        require(_duration \u003e 0);\n        auctionDetails memory _auction = auctionDetails({\n        seller: msg.sender,\n        price: _price,\n        duration: _duration,\n        tokenAddress: _tokenAddress,\n        isActive: true\n        });\n        address owner = msg.sender;\n        IERC721(_nft).safeTransferFrom(owner, address(this), _tokenId);\n        tokenToAuction[_nft][_tokenId] = _auction;\n\n        emit StartAuction(owner, _tokenId, _price, _duration);\n    }\n```\n\n- 购买  \n  同理在 purchaseNFTToken 接口, 即购买接口中, 会调用 IERC20(auction.tokenAddress).transferFrom(msg.sender,seller,price) , 即用户需要对 Auction 合约进行 ERC20 的 approve 授权, 这里是调用 WETH 的 approve 对 Auction 合约进行授权\n\n```\nfunction purchaseNFTToken(address _nft, uint256 _tokenId) external {\n        auctionDetails storage auction = tokenToAuction[_nft][_tokenId];\n        require(auction.duration \u003e block.timestamp, \"Deadline already passed\");\n        //require(auction.seller == msg.sender);\n        require(auction.isActive);\n        auction.isActive = false;\n        address seller = auction.seller;\n        uint price = auction.price;\n        require(IERC20(auction.tokenAddress).transferFrom(msg.sender,seller,price), \"erc 20 transfer failed!\");\n\n        IERC721(_nft).safeTransferFrom(address(this),msg.sender , _tokenId);\n\n        emit AuctionEnd(seller, msg.sender, _tokenId, price, auction.duration);\n    }\n```\n\n## deploy address\n\npolygon mainnet\n\n- Auction 0x9089F4F3a19bdF13816e7c940d9376De32CFE2Fd\n- NFT 0xFD5f96fcFB68E80AcfEDd89841d9A354B93f53af\n- WMATIC 0x0d500b1d8e8ef31e21c99d1db9a6444d3adf1270\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F0x-stan%2Fwatermargin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F0x-stan%2Fwatermargin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F0x-stan%2Fwatermargin/lists"}