BTC
ETH
HTX
SOL
BNB
ดูตลาด
简中
繁中
English
日本語
한국어
ภาษาไทย
Tiếng Việt

เรียนรู้วิธีสร้างตัวแยกการชำระเงินโทเค็น ERC20 ของคุณเองในบทความเดียว

星球君的朋友们
Odaily资深作者
บทความนี้มีประมาณ 11750 คำ การอ่านทั้งหมดใช้เวลาประมาณ 17 นาที
วันนี้เราจะเรียนรู้วิธีสร้างตัวแบ่งการชำระเงินโทเค็น ERC20 ของเราเอง ซึ่งสามารถรวมเข้ากับโ
สรุปโดย AI
วันนี้เราจะเรียนรู้วิธีสร้างตัวแบ่งการชำระเงินโทเค็น ERC20 ของเราเอง ซึ่งสามารถรวมเข้ากับโ

การชำระเงินเป็นหัวข้อที่เกิดซ้ำในเกือบทุกพื้นที่ของสกุลเงินดิจิทัล โดยเฉพาะอย่างยิ่งการเสนอการชำระเงินให้กับผู้วางเดิมพันหลายคน ตัวอย่างเช่น DAO ต้องการระดมทุนหลายโครงการ DEX ต้องการรวมเพื่อกระจายค่าธรรมเนียมการทำธุรกรรมให้กับผู้เข้าร่วมบางคน หรือทีมต้องการแจกจ่ายโทเค็นให้กับสมาชิกในทีมเป็นเงินเดือน

ชื่อระดับแรก

วันนี้เราจะเรียนรู้วิธีสร้างตัวแบ่งการชำระเงินโทเค็น ERC20 ของเราเอง ซึ่งสามารถรวมเข้ากับโครงการใดก็ได้!

ข้อกำหนดเบื้องต้นและการตั้งค่า

ชื่อเรื่องรอง

โครงสร้างโครงการ

เราจะสร้างสัญญาสองฉบับ อันแรกจะเป็นสัญญาสมาร์ทแยกการชำระเงินโทเค็น ERC20 และอันที่สองจะเป็นสัญญาสมาร์ทพูลจำลอง สัญญาสมาร์ทตัวแยกการชำระเงินโทเค็น ERC20 จะเป็นนามธรรมและมีตรรกะและข้อมูลสำหรับการจัดการผู้ส่งและผู้ชำระเงินและส่วนการชำระเงินที่เกี่ยวข้อง พูลจำลองจะสืบทอดตัวแยกการชำระเงินโทเค็น ERC20 เพื่อให้เราสามารถกระจายการชำระเงินไปยังนักเดิมพันหลายคนโดยอัตโนมัติ มีเหตุผลสองประการในการแยกฟังก์ชันการชำระเงินออกเป็นสองสัญญา:

  • สาธิตการใช้สัญญาแยกการชำระเงินด้วยโทเค็นในกรณีการใช้งานจริง

  • ตรวจสอบให้แน่ใจว่าสัญญาแยกการชำระเงินโทเค็นมีความยืดหยุ่นเพียงพอสำหรับทุกคนที่จะเลือกและรวมเข้ากับโครงการของตนเอง

ชื่อเรื่องรอง

ตั้งค่าสภาพแวดล้อมการพัฒนา

เครื่องมือในบทช่วยสอนนี้:

  • Hardhat - สภาพแวดล้อมการพัฒนาสัญญาอัจฉริยะ

  • OpenZeppelin - เทมเพลตสัญญาอัจฉริยะที่ผ่านการตรวจสอบแล้ว

เริ่มโครงการ NPM ด้วย NPM init -y ในไดเร็กทอรีว่าง

หลังจากตั้งค่าโปรเจ็กต์แล้ว ให้ติดตั้ง Hardhat ด้วยคำสั่งต่อไปนี้:

หลังจากติดตั้ง Hardhat แล้ว ให้พิมพ์ npx Hardhat แล้วเลือกตัวเลือกเพื่อสร้างโครงการตัวอย่างพื้นฐาน ซึ่งรวมถึงโครงสร้างไฟล์ที่สะดวกเพื่อสร้าง ทดสอบ และปรับใช้สัญญาของคุณเองได้อย่างง่ายดาย

เลือกสร้างโครงการตัวอย่างพื้นฐาน

คุณสามารถลบไฟล์ Greeter.sol ในโฟลเดอร์สัญญา และลบไฟล์ sample-test.js ออกจากโฟลเดอร์ทดสอบ

นอกจากนี้ เราจะติดตั้งไลบรารีปลั๊กอินหมวกนิรภัย ซึ่งเป็นปลั๊กอินหมวกนิรภัย พวกเขาช่วยให้เราสามารถเพิ่มเครื่องมือสำหรับการทดสอบและปรับใช้สัญญาอัจฉริยะ

ที่ด้านบนของไฟล์ hardhat.config.js ให้เพิ่ม

ต้องติดตั้งแพ็คเกจที่เรียกว่า chai เพื่อทดสอบสัญญาอัจฉริยะของเรา

ชื่อเรื่องรอง

สร้างตัวแบ่งการชำระเงินโทเค็น

สัญญาสมาร์ทแยกการชำระเงินด้วยโทเค็นนี้จะให้ตรรกะในการตั้งค่าและจัดเก็บข้อมูลที่เกี่ยวข้องกับรายชื่อผู้รับเงินและส่วนแบ่งของผู้รับเงินแต่ละราย ผู้รับเงินแต่ละคนถือหุ้นเท่ากับเปอร์เซ็นต์ของเงินทุนที่พวกเขาควรได้รับ (เช่น หากมีผู้รับเงิน 4 คน แต่ละคนถือ 5 หุ้น พวกเขาแต่ละคนจะได้รับ 25% ของการจ่ายเงินใดๆ)

ในการเริ่มสัญญานี้ เราจะสร้างไฟล์ใหม่ในโฟลเดอร์สัญญาของเรา และตั้งชื่อว่า TokenPaymentSplitter.sol

ตั้งค่าบรรทัด Pragma และเปลือกสัญญา

pragma solidity ^0.8.0;
abstract contract TokenPaymentSplitter {

}

โปรดทราบว่านี่เป็นสัญญานามธรรม เราจะนำเข้าสู่สัญญาพูลจำลองในภายหลัง การทำให้เป็นแบบนามธรรมยังช่วยให้เราสามารถนำเข้าสัญญานี้ไปยังโครงการจริงอื่น ๆ ในอนาคตได้อย่างง่ายดาย

ตอนนี้มานำเข้าเครื่องมือที่มีประโยชน์จาก OpenZeppelin

pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
abstract contract TokenPaymentSplitter {
   using SafeERC20 for IERC20;

}

SafeERC20.sol มีอินเทอร์เฟซ ERC20 ที่ช่วยให้เราสามารถเรียกใช้ฟังก์ชันมาตรฐานจากสัญญาอัจฉริยะ ERC20 ใดๆ และรวมการเรียกเหล่านี้ไว้ในฟังก์ชันเพิ่มเติมเพื่อให้วิธีการโอนโทเค็นที่ปลอดภัยยิ่งขึ้น

ตอนนี้เราจะสร้างตัวแปรเพื่อเก็บข้อมูลสัญญา

abstract contract TokenPaymentSplitter {
   using SafeERC20 for IERC20;
   
   address internal paymentToken;
   uint256 internal _totalShares;
   uint256 internal _totalTokenReleased;
   address[] internal _payees;
   mapping(address => uint256) internal _shares;
   mapping(address => uint256) internal _tokenReleased;
   

}

paymentToken คือที่อยู่ของโทเค็น ERC20 ที่เราใช้สำหรับการชำระเงิน

_totalShares เป็นการรวมหุ้นจากผู้รับเงินทั้งหมด

_totalTokenReleased คือโทเค็นการชำระเงินทั้งหมดที่จ่ายให้กับผู้รับเงินทั้งหมด

_payees ให้อาร์เรย์ของที่อยู่ผู้รับเงินปัจจุบันทั้งหมด

_shares คือการแมปที่อยู่ของผู้รับกับจำนวนการแชร์ที่กำหนดให้

_tokenReleased เป็นการแมปที่อยู่ของผู้รับกับจำนวนโทเค็นการชำระเงิน

ตอนนี้วางตัวสร้างที่ยอมรับสามพารามิเตอร์ พารามิเตอร์แรกคืออาร์เรย์ของผู้รับเงินที่เราต้องการเริ่มต้นในการปรับใช้สัญญา พารามิเตอร์ที่สองคืออาร์เรย์ของการแบ่งปันสำหรับผู้รับเงินแต่ละคน ที่สามคือที่อยู่ของโทเค็น ERC20 ที่จะใช้ในการชำระเงิน

pragma solidity 0.8.0
constructor(
   address[] memory payees,
   uint256[] memory shares_,
   address _paymentToken
) {
   require(
       payees.length == shares_.length,
       "TokenPaymentSplitter: payees and shares length mismatch"
   );
   require(payees.length > 0, "TokenPaymentSplitter: no payees");
   for (uint256 i = 0; i < payees.length; i++) {
       _addPayee(payees[i], shares_[i]);
   }
   paymentToken = _paymentToken;

}

คอนสตรัคเตอร์ประกอบด้วยคำสั่ง need เพื่อให้แน่ใจว่าอาร์เรย์ทั้งสองมีความยาวเท่ากัน เพื่อให้ผู้รับเงินแต่ละคนได้รับส่วนแบ่งของตน มีคำสั่งอื่นที่จำเป็นเพื่อให้แน่ใจว่าสัญญาเริ่มต้นโดยมีผู้รับเงินอย่างน้อยหนึ่งราย

นอกจากนี้ยังมี for loop ซึ่งกำหนดผู้รับเงินแต่ละคนและส่วนแบ่งของพวกเขาให้กับตัวแปรที่เราสร้างขึ้นด้านบน เสร็จสิ้นด้วยฟังก์ชันที่ชื่อว่า _addPayee ซึ่งเราจะสร้างขึ้นในไม่ช้า

เมื่อคอนสตรัคเตอร์เข้าที่แล้ว ให้เพิ่มฟังก์ชันอีกเล็กน้อยเพื่อเรียกและรับตัวแปรสัญญา

pragma solidity 0.8.0
function totalShares() public view returns (uint256) {
   return _totalShares;
}
function shares(address account) public view returns (uint256) {
   return _shares[account];
}
function payee(uint256 index) public view returns (address) {
   return _payees[index];

}

ตอนนี้เราจะสร้างฟังก์ชั่นสำหรับเพิ่มผู้รับเงิน

pragma solidity 0.8.0;
function _addPayee(address account, uint256 shares_) internal {
   require(
       account != address(0),
       "TokenPaymentSplitter: account is the zero address"
   );
   require(shares_ > 0, "TokenPaymentSplitter: shares are 0");
   require(
       _shares[account] == 0,
       "TokenPaymentSplitter: account already has shares"
   );
   _payees.push(account);
   _shares[account] = shares_;
   _totalShares = _totalShares + shares_;

}

_addPayee เป็นฟังก์ชันที่เราเรียกในตัวสร้างเพื่อตั้งค่าอาร์เรย์ผู้รับเงิน ฟังก์ชันนี้ใช้สองพารามิเตอร์ บัญชีผู้รับเงินและจำนวนหุ้นที่เกี่ยวข้อง จากนั้นจะตรวจสอบว่าบัญชีมีที่อยู่เป็นศูนย์หรือไม่ ส่วนแบ่งมากกว่าศูนย์หรือไม่ และบัญชีได้รับการลงทะเบียนเป็นผู้รับเงินแล้วหรือไม่ หากผ่านการตรวจสอบทั้งหมด เราจะเพิ่มข้อมูลให้กับตัวแปรที่เกี่ยวข้อง

ตอนนี้มาเพิ่มฟังก์ชันเพื่อรองรับการแจกจ่ายโทเค็นไปยังผู้รับเงิน

pragma solidity 0.8.0;
function release(address account) public virtual {
   require(
       _shares[account] > 0, "TokenPaymentSplitter: account has no shares"
   );
   
   uint256 tokenTotalReceived = IERC20(paymentToken).balanceOf(address(this)) + _totalTokenReleased;
   
   uint256 payment = (tokenTotalReceived * _shares[account]) / _totalShares - _tokenReleased[account];
   
   require(payment != 0, "TokenPaymentSplitter: account is not due payment");
   _tokenReleased[account] = _tokenReleased[account] + payment;
   _totalTokenReleased = _totalTokenReleased + payment;
   IERC20(paymentToken).safeTransfer(account, payment);
}

Release เป็นฟังก์ชันที่ทุกคนสามารถเรียกได้ ซึ่งใช้อาร์กิวเมนต์ของบัญชีผู้รับเงินที่มีอยู่ ลองวิเคราะห์สิ่งที่เกิดขึ้นในฟังก์ชันนี้ ขั้นแรก จะตรวจสอบว่าบัญชีมีการแบ่งปันที่กำหนดให้หรือไม่ จากนั้นจะสร้างตัวแปรที่เรียกว่า tokenTotalReceived ซึ่งจะเพิ่มยอดโทเค็นปัจจุบันของสัญญาให้กับจำนวนโทเค็นทั้งหมดที่เผยแพร่ก่อนหน้านี้ สร้างตัวแปรอื่นที่เรียกว่าการชำระเงินซึ่งกำหนดจำนวนโทเค็นที่ได้รับทั้งหมดที่เป็นหนี้ในบัญชี จากนั้นลบจำนวนเงินที่ได้รับในบัญชี จากนั้น ใบแจ้งยอดที่จำเป็นจะตรวจสอบเพื่อดูว่าจำนวนเงินที่ชำระปัจจุบันมากกว่าศูนย์หรือไม่ (เช่น มีโทเค็นค้างชำระอยู่ในปัจจุบัน) หากการตรวจสอบผ่าน ให้อัปเดต tokenReleased ของบัญชีและอัปเดต totalTokenReleased ในที่สุดจำนวนเงินโทเค็นที่จ่ายไปยังบัญชีจะถูกโอน

ตอนนี้ฟังก์ชั่นเข้าที่แล้ว! แต่สัญญานี้มีอีกอย่างที่ต้องทำ...อีเวนต์!

เราจะเพิ่มกิจกรรมสองรายการในสัญญา การเพิ่มกิจกรรมที่ด้านบนสุดของสัญญาถือเป็นแนวทางปฏิบัติที่ดี

pragma solidity 0.8.0;
event PayeeAdded(address account, uint256 shares);

event PaymentReleased(address to, uint256 amount);

เมื่อเหตุการณ์เหล่านี้รวมอยู่ในสัญญา เราจะเผยแพร่ในหน้าที่ที่เหมาะสม

pragma solidity 0.8.0;
function _addPayee(address account, uint256 shares_) internal {
   ///existingFunctionCode
   emit PayeeAdded(account, shares_);
}
function release(address account) public virtual {
   ///existingFunctionCode
   emit PaymentReleased(account, payment);

}

ชื่อเรื่องรอง

สร้างสัญญาพูลจำลอง

สัญญานี้จะไม่ซับซ้อนมากนัก เนื่องจากเราเพียงต้องการสาธิตวิธีผสานรวมตัวแยกการชำระเงินด้วยโทเค็น สัญญานี้ได้รับโทเค็น ERC20 เป็นระยะๆ ซึ่งเราต้องการแจกจ่ายให้กับรายชื่อผู้รับเงิน โทเค็น ERC20 นี้สามารถมาถึงได้ในสถานการณ์ต่างๆ เช่น เงินฝากของผู้ใช้หรือค่าธรรมเนียมการเปลี่ยนเส้นทางจากสัญญาอัจฉริยะอื่น ในชีวิตจริง อาจมีสัญญาที่ซับซ้อนกว่านี้ซึ่งมีฟังก์ชันมากกว่าเพื่อตอบสนองกรณีการใช้งานของผู้ใช้ ทั้งนี้ขึ้นอยู่กับโครงการ

ในโฟลเดอร์สัญญา ให้สร้างไฟล์ใหม่ชื่อ MockPool.sol จากนั้นเพิ่มรหัสต่อไปนี้

pragma solidity ^0.8.0;
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "./TokenPaymentSplitter.sol";
contract MockPool is Ownable, TokenPaymentSplitter {
   using SafeERC20 for IERC20;
   constructor(
       address[] memory _payees,
       uint256[] memory _shares,
       address _paymentToken
   ) TokenPaymentSplitter(_payees, _shares, _paymentToken) {}
   
   function drainTo(address _transferTo, address _token) public onlyOwner {
       require(
       _token != paymentToken,
       "MockPool: Token to drain is PaymentToken"
       );
       uint256 balance = IERC20(_token).balanceOf(address(this));
       require(balance > 0, "MockPool: Token to drain balance is 0");
       IERC20(_token).safeTransfer(_transferTo, balance);
   }

}

ในสัญญานี้นำเข้าสามสิ่ง อย่างแรกคือยูทิลิตี้ที่เป็นเจ้าของได้ของ OpenZeppelin ซึ่งใช้ตัวดัดแปลงเฉพาะเจ้าของเฉพาะในบางฟังก์ชัน ประการที่สองคือ SafeERC20 ซึ่งอนุญาตให้โอนโทเค็น ERC20 ที่ปลอดภัยดังที่จะเห็นในสัญญา ประการที่สามคือสัญญา TokenPaymentSplitter ของเรา

ในตัวสร้าง MockPool เราต้องการพารามิเตอร์สามตัวเดียวกันจาก TokenPaymentSplitter เราแค่ส่งต่อไปยังสัญญาที่รับมาของเรา

ชื่อเรื่องรอง

ทดสอบสัญญา

การทดสอบสัญญาอัจฉริยะมีความสำคัญพอๆ กับการสร้างสัญญาอัจฉริยะ สินทรัพย์ที่สัญญาเหล่านี้จัดการมักจะเป็นของบุคคลอื่น ดังนั้น จึงเป็นความรับผิดชอบของเราในฐานะนักพัฒนาที่ต้องตรวจสอบให้แน่ใจว่าสินทรัพย์เหล่านั้นทำงานได้ตามที่ควรจะเป็น และการทดสอบของเราครอบคลุมเกือบทุกกรณี

การทดสอบที่จะดำเนินการต่อไปนี้เป็นตัวอย่างบางส่วนที่แสดงให้เห็นว่าสัญญาอัจฉริยะ TokenPaymentSplitter ทำงานตามที่เราคาดไว้ เมื่อทำงานในโครงการของคุณเอง คุณอาจต้องการสร้างการทดสอบที่ปรับให้เหมาะกับกรณีการใช้งานของคุณโดยเฉพาะ

เพื่อสนับสนุนการทดสอบของเรา เราต้องการรวมโทเค็น ERC20 สำหรับสิ่งนี้ เราจะสร้างไฟล์ solididity ใหม่ที่นำเข้าเทมเพลต OpenZepplin ERC20 เพื่อใช้ในการทดสอบของเรา ในโฟลเดอร์สัญญา สร้างไฟล์ใหม่ชื่อ Imports.sol และรวมรหัสต่อไปนี้:

pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC20/presets/ERC20PresetMinterPauser.sol";

contract Imports {}

ตอนนี้ สร้างไฟล์ชื่อ test.js ในโฟลเดอร์ทดสอบ ที่ด้านบนของไฟล์นี้ เราจะนำเข้าแพ็คเกจที่รองรับการทดสอบของเรา

const { expect } = require('chai')

const { ethers } = require('hardhat')

ตอนนี้ เพื่อตั้งค่าการทดสอบ ก่อนอื่นเราจะสร้างตัวแปรที่จำเป็น สร้างฟังก์ชัน beforeEach ซึ่งถูกเรียกใช้ก่อนการทดสอบแต่ละครั้ง และสร้างฟังก์ชันอธิบายที่ว่างเปล่า ซึ่งจะมีการทดสอบของเราในไม่ช้า

describe('TokenPaymentSplitter Tests', () => {
let deployer
let account1
let account2
let account3
let account4
let testPaymentToken
let mockPool
beforeEach(async () => {
   [deployer, account1, account2, account3, account4] = await ethers.getSigners()
   const TestPaymentToken = await ethers.getContractFactory('ERC20PresetMinterPauser')
   testPaymentToken = await TestPaymentToken.deploy('TestPaymentToken', 'TPT')
   await testPaymentToken.deployed()
})
 
describe('Add payees with varying amounts and distribute payments', async () => {}

}

ชื่อระดับแรก

โทเค็นการชำระเงินมีการกระจายอย่างเท่าเทียมกันระหว่างผู้รับเงินหลายคน

ในการทดสอบครั้งแรก เราต้องการดูว่าเกิดอะไรขึ้นเมื่อเราปรับใช้สัญญาที่มีรายชื่อผู้รับเงินที่มีส่วนแบ่งที่กระจายเท่าๆ กัน ด้านล่างนี้คือรหัสทดสอบ

it('payment token is distributed evenly to multiple payees', async () => {
   payeeAddressArray = [account1.address, account2.address, account3.address, account4.address]
   payeeShareArray = [10, 10, 10, 10]
   const MockPool = await ethers.getContractFactory('MockPool')
   mockPool = await MockPool.deploy(
       payeeAddressArray,
       payeeShareArray,
       testPaymentToken.address
   )
   await mockPool.deployed()
   await testPaymentToken.mint(mockPool.address, 100000)
   await mockPool
       .connect(account1)
       .release(account1.address)
   await mockPool
       .connect(account2)
       .release(account2.address)
   await mockPool
       .connect(account3)
       .release(account3.address)
   await mockPool
       .connect(account4)
       .release(account4.address)
   const account1TokenBalance = await testPaymentToken.balanceOf(account1.address)
   const account2TokenBalance = await testPaymentToken.balanceOf(account2.address)
   const account3TokenBalance = await testPaymentToken.balanceOf(account3.address)
   const account4TokenBalance = await testPaymentToken.balanceOf(account4.address)
   expect(account1TokenBalance).to.equal(25000)
   expect(account2TokenBalance).to.equal(25000)
   expect(account3TokenBalance).to.equal(25000)
   expect(account4TokenBalance).to.equal(25000)

})

ชื่อระดับแรก

โทเค็นการชำระเงินมีการกระจายอย่างไม่เท่าเทียมกันระหว่างผู้รับเงินหลายคน

ในการทดสอบครั้งที่สอง เราต้องการให้แน่ใจว่าคณิตศาสตร์นั้นใช้ได้แม้ว่าการแบ่งปันของผู้รับแต่ละคนจะกระจายไม่เท่ากันก็ตาม

it('payment token is distributed unevenly to multiple payees', async () => {
   payeeAddressArray = [account1.address, account2.address, account3.address, account4.address]
   payeeShareArray = [10, 5, 11, 7]
   const MockPool = await ethers.getContractFactory('MockPool')
   mockPool = await MockPool.deploy(
       payeeAddressArray,
       payeeShareArray,
       testPaymentToken.address
   )
   await mockPool.deployed()
   await testPaymentToken.mint(mockPool.address, 100000)
   await mockPool
       .connect(account1)
       .release(account1.address)
   await mockPool
       .connect(account2)
       .release(account2.address)
   await mockPool
       .connect(account3)
       .release(account3.address)
   await mockPool
       .connect(account4)
       .release(account4.address)
   const mockPoolTestPaymentTokenBalance = await testPaymentToken.balanceOf(
       mockPool.address
   )
   const account1TokenBalance = await testPaymentToken.balanceOf(account1.address)
   const account2TokenBalance = await testPaymentToken.balanceOf(account2.address)
   const account3TokenBalance = await testPaymentToken.balanceOf(account3.address)
   const account4TokenBalance = await testPaymentToken.balanceOf(account4.address)
   expect(mockPoolTestPaymentTokenBalance).to.equal(1)
   expect(account1TokenBalance).to.equal(30303)
   expect(account2TokenBalance).to.equal(15151)
   expect(account3TokenBalance).to.equal(33333)
   expect(account4TokenBalance).to.equal(21212)

})

ชื่อระดับแรก

โทเค็นการชำระเงินมีการกระจายอย่างไม่เท่าเทียมกันไปยังผู้รับเงินหลายราย และโทเค็นการชำระเงินเพิ่มเติมจะถูกส่งไปยังกลุ่ม

สิ่งนี้คล้ายกับการทดสอบก่อนหน้านี้ แต่ด้วยการเพิ่มโทเค็นการชำระเงินเพิ่มเติมที่ถูกส่งไปยังกลุ่มก่อนที่เงินจะถูกปล่อยไปยังผู้รับ สิ่งนี้แสดงให้เห็นว่าในขณะที่โทเค็นการชำระเงินยังคงไหลเข้าสู่สัญญาพูลจำลอง คณิตศาสตร์ยังสามารถรับประกันได้ว่าผู้รับเงินจะได้รับจำนวนเงินที่ถูกต้อง

it('payment token is distributed unevenly to multiple payees with additional payment token sent to pool', async () => {
   payeeAddressArray = [account1.address, account2.address, account3.address, account4.address]
   payeeShareArray = [10, 5, 11, 7]
   const MockPool = await ethers.getContractFactory('MockPool')
   mockPool = await MockPool.deploy(
       payeeAddressArray,
       payeeShareArray,
       testPaymentToken.address
   )
   await mockPool.deployed()
   await testPaymentToken.mint(mockPool.address, 100000)
   await mockPool
       .connect(account1)
       .release(account1.address)
   await mockPool
       .connect(account2)
       .release(account2.address)
   await testPaymentToken.mint(mockPool.address, 100000)
   await mockPool
       .connect(account3)
       .release(account3.address)
   await mockPool
       .connect(account4)
       .release(account4.address)
   await mockPool
       .connect(account1)
       .release(account1.address)
   await mockPool
       .connect(account2)
       .release(account2.address)
   const mockPoolTestPaymentTokenBalance = await testPaymentToken.balanceOf(
       mockPool.address
           )
   const account1TokenBalance = await testPaymentToken.balanceOf(account1.address)
   const account2TokenBalance = await testPaymentToken.balanceOf(account2.address)
   const account3TokenBalance = await testPaymentToken.balanceOf(account3.address)
   const account4TokenBalance = await testPaymentToken.balanceOf(account4.address)
   expect(mockPoolTestPaymentTokenBalance).to.equal(1)
   expect(account1TokenBalance).to.equal(60606)
   expect(account2TokenBalance).to.equal(30303)
   expect(account3TokenBalance).to.equal(66666)
   expect(account4TokenBalance).to.equal(42424)

})

เมื่อการทดสอบทั้งหมดพร้อมแล้ว ก็ถึงเวลาเรียกใช้และดูว่าได้ผลหรือไม่ ในโฟลเดอร์รูทของโปรเจ็กต์ ให้เริ่มการทดสอบด้วย npx hardhat test หากทุกอย่างถูกต้อง คุณจะเห็นสี่เหลี่ยมสีเขียวทั้งหมดดังที่แสดงในภาพด้านล่าง

สรุป

สรุป

บทความนี้มาจากชุมชนการเงินแบบกระจายศูนย์และทำซ้ำโดยได้รับอนุญาต

Source:https://medium.com/coinmonks/create-an-erc20-token-payment-splitting-smart-contract-c79436470ccc

บทความนี้มาจากชุมชนการเงินแบบกระจายศูนย์และทำซ้ำโดยได้รับอนุญาต

ETH
ยินดีต้อนรับเข้าร่วมชุมชนทางการของ Odaily
กลุ่มสมาชิก:
https://t.me/Odaily_News
กลุ่มสนทนา:
https://t.me/Odaily_GoldenApe
บัญชีทางการ:
https://twitter.com/OdailyChina
สารบัญบทความ
อันดับบทความร้อน
Daily
Weekly
ดาวน์โหลดแอพ Odaily พลาเน็ตเดลี่
ให้คนบางกลุ่มเข้าใจ Web3.0 ก่อน
IOS
Android