You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. import * as dotevnv from "dotenv"
  2. import {toUtf8String,parseUnits,ContractFactory, parseEther,JsonRpcProvider, Contract, JsonRpcSigner, Wallet,ContractTransactionResponse, MaxInt256
  3. ,Transaction,formatEther,
  4. ZeroHash,ethers,keccak256,id
  5. } from 'ethers'
  6. import chalk from "chalk";
  7. import {Calulator} from "../inc/calc";
  8. import { TokenIssuer } from "../inc/TokenIssuer";
  9. import {
  10. SecurityToken,
  11. SecurityToken__factory,
  12. } from '../typechain'
  13. // import { HardhatEthersSigner } from "@nomicfoundation/hardhat-ethers/signers";
  14. import { Partition } from '../inc/tokenData';
  15. import {checkReceipt,checkReceipt2, setProvider,getDeploymentAddresses,
  16. getElapsed, sleep,getBlockInfo} from '../inc/util'
  17. dotevnv.config();
  18. if (!process.env.RPCURL) {
  19. console.log(`No rpcur value specified...`)
  20. }
  21. console.log(`목적 서버 : ${process.env.RPCURL}`);
  22. async function getNonce(addr: string): Promise<number> {
  23. const nonce = await provider.getTransactionCount(addr);
  24. return nonce;
  25. }
  26. async function info(symbol: string) {
  27. const proxy = getDeploymentAddresses(symbol).address;
  28. console.log(`토큰 주소 : ${proxy}`);
  29. const token = new SecurityToken__factory(issuer).attach(proxy) as SecurityToken;
  30. await token.connect(admin);
  31. const ops = await token.operators();
  32. console.log(ops);
  33. // token.grantRole(keccak256('OPERATOR_ROLE'),'0xaaa')
  34. }
  35. async function transfer(signer:Wallet,symbol:string,from: Wallet, to: Wallet, amount: number = 1, count: number = 1) {
  36. const proxy = getDeploymentAddresses(symbol).address;
  37. console.log(`토큰 주소 : ${proxy}`);
  38. const token = new SecurityToken__factory(issuer).attach(proxy) as SecurityToken;
  39. await token.connect(admin);
  40. // const ops = await token.operators();
  41. // console.log(ops);
  42. let balance1= await token.balanceOf(from);
  43. let balance2 = await token.balanceOf(to);
  44. const b = await token.isTokenHolderKYC(from);
  45. if(!b) {
  46. console.log('holder kyc error');
  47. //return;
  48. }
  49. const partitions = await token.getDefaultPartitions();
  50. console.log(chalk.yellow('###################### 전송전 잔고 ###################################'))
  51. console.log(`balance of sender(${from.address}) = ${balance1}\r\nbalance of receiver(${to.address}) = ${balance2}`);
  52. // token.on(token.filters.Transfer, async (...args) => {
  53. // const lastArg = args[args.length - 1];
  54. // console.log(lastArg);
  55. // console.log('on transfer by partition');
  56. // })
  57. let nonce = await getNonce(signer.address);
  58. let txids = [];
  59. let proms = [];
  60. let firstTx:string = null;
  61. let lastTx:string = null;
  62. const start = Date.now();
  63. console.log(chalk.cyan(`전송시작 시간 : ${new Date(start).toUTCString()}`));
  64. console.log(chalk.yellow(`sending ${count} transactions`));
  65. for(let i = 0; i < count; i++) {
  66. const tx = await token.operatorTransferByPartition.populateTransaction(
  67. partitions[0],
  68. from.address,
  69. to.address,
  70. amount,
  71. ZeroHash,
  72. ZeroHash,
  73. {
  74. // gasPrice: 0,
  75. gasLimit: 2100000,
  76. nonce: nonce,
  77. type: 2,
  78. chainId: 1337
  79. }
  80. );
  81. ++nonce;
  82. // console.log(tx);
  83. const signed = await signer.signTransaction(tx);
  84. const pm = provider.send('eth_sendRawTransaction',[signed]);
  85. if(i == 0) {
  86. firstTx = keccak256(signed);
  87. }
  88. if (i == count -1) {
  89. lastTx = keccak256(signed);
  90. }
  91. proms.push(pm);
  92. }
  93. let txs = await Promise.all(proms);
  94. const elapsed = getElapsed(start,1000);
  95. console.log(`all tx sent in ${elapsed} seconds`);
  96. console.log(`first Tx = ${firstTx}`);
  97. console.log(`last Tx = ${lastTx}`);
  98. let txMap = new Map<string,boolean>();
  99. txs.forEach(txid => {
  100. // txids.push({txid: txid});
  101. txMap.set(txid,false);
  102. });
  103. const blockHashes = await checkReceipt2(txMap,[firstTx as string, lastTx as string], 'wait for receipt...');
  104. const firstBlockHash = blockHashes.get(firstTx);
  105. const lastBlockHash = blockHashes.get(lastTx);
  106. console.log(`firstBlockHash = ${firstBlockHash} \nlastBlockHash = ${lastBlockHash}`);
  107. balance1= await token.balanceOf(from);
  108. balance2 = await token.balanceOf(to);
  109. console.log(chalk.yellow('###################### 전송후 잔고 ###################################'))
  110. console.log(`balance of sender(${from.address}) = ${balance1}\r\nbalance of receiver(${to.address}) = ${balance2}`);
  111. // console.log(`balance of sender = ${balance1}, balance of receiver = ${balance2}`);
  112. const lastB = await getBlockInfo(lastBlockHash);
  113. const lastTimeStamp = parseInt(lastB.timestamp,16);
  114. console.log(`eth_getBlockByHash(${lastBlockHash}).timestamp = ${lastTimeStamp}`)
  115. const d = new Date(lastTimeStamp * 1000);
  116. console.log(chalk.cyan(`전송종료 시간(블록완결시간) : ${d.toUTCString()}`));
  117. console.log(chalk.yellow(`start timestamp = ${start}`));
  118. console.log(chalk.yellow(`end timestamp = ${lastTimeStamp * 1000}`));
  119. const tps = calc.CTPS(count,start,lastTimeStamp * 1000);
  120. console.log(`CTPS = ${tps}`);
  121. }
  122. async function testSecurity(symbol: string, operator: Wallet, tobeOperator: Wallet,holder: Wallet, user1: Wallet, user2: Wallet) {
  123. const proxy = getDeploymentAddresses(symbol).address;
  124. console.log(`토큰 주소 : ${proxy}`);
  125. const token = new SecurityToken__factory(operator).attach(proxy) as SecurityToken;
  126. await token.connect(operator);
  127. const decimals = await token.decimals();
  128. const digit = 10 ** Number(decimals);
  129. console.log(`토큰 자릿수 : ${decimals}`);
  130. const partitions = await token.getDefaultPartitions();
  131. //console.log(partitions);
  132. console.log(chalk.yellow('###################### 변경전 오퍼레이터 ###################################'))
  133. const ops = await token.operators();
  134. console.log(ops);
  135. console.log(chalk.yellow(`provided operator = ${operator.address}`));
  136. console.log(chalk.yellow('###################### KYC 전 사용자 잔고 ###################################'))
  137. let b = await token.balanceOf(holder);
  138. let holderBalance = (1/digit) * Number(b);
  139. console.log(`토큰보유자 잔고 = ${Number(holderBalance).toFixed(Number(decimals))}`);
  140. b = await token.balanceOf(user1);
  141. let bUser1 = Number((1/digit) * Number(b));
  142. b = await token.balanceOf(user2);
  143. let bUser2 = Number((1/digit) * Number(b));
  144. console.log(chalk.blue(
  145. `사용자1 잔고 : ${Number(bUser1).toFixed(Number(decimals))}\r\n사용자2 잔고 : ${Number(bUser2).toFixed(Number(decimals))}`
  146. ))
  147. console.log(chalk.bgCyan('###################### 사용자 권한테스트 시작 ###################################'))
  148. console.log(chalk.yellow('###################### 사용자 등록전 전송시도###################################'))
  149. if(await token.isTokenHolderKYC(user1)) {
  150. console.log(`user1 already kyced .. unKYC user1`);
  151. const r = await token.unKYCtokenHolders([user1]);
  152. await r.wait();
  153. }
  154. if(await token.isTokenHolderKYC(user2)) {
  155. console.log(`user2 already kyced .. .. unKYC user2`);
  156. const r = await token.unKYCtokenHolders([user2]);
  157. await r.wait();
  158. }
  159. try {
  160. let r = await token.operatorTransferByPartition(partitions[0],holder,user1,1 * digit,ZeroHash,ZeroHash,{gasLimit: 20000000});
  161. console.log(`txhash1 : ${r.hash}`)
  162. const receipt1 = await r.wait();
  163. console.log(receipt1.hash);
  164. r = await token.operatorTransferByPartition(partitions[0],holder,user2,1 * digit,ZeroHash,ZeroHash,{gasLimit: 20000000});
  165. const receipt2 = await r.wait();
  166. console.log(`txhash2 : ${r.hash}`)
  167. console.log('KYC전 토큰전송완료....');
  168. } catch(ex) {
  169. console.log(chalk.red('예정된 KYC전 토큰전송에러'));
  170. //console.log(ex);
  171. }
  172. console.log(chalk.yellow('###################### 사용자 등록(KYC) ###################################'))
  173. let ret = await token.KYCtokenHolders([user1,user2],{gasLimit: 20000000});
  174. console.log('wait for user KYCed...');
  175. await ret.wait();
  176. console.log(chalk.yellow('###################### 사용자 등록후 전송시도 ###################################'))
  177. ret = await token.operatorTransferByPartition(partitions[0],holder,user1,1 * digit ,ZeroHash,ZeroHash,{gasLimit: 20000000});
  178. console.log(`txhash1 : ${ret.hash}`)
  179. let receipt = await ret.wait();
  180. console.log(receipt.hash);
  181. ret = await token.operatorTransferByPartition(partitions[0],holder,user2,1 * digit ,ZeroHash,ZeroHash,{gasLimit: 20000000});
  182. console.log(`txhash2 : ${ret.hash}`)
  183. receipt = await ret.wait();
  184. console.log(receipt.hash);
  185. console.log(chalk.yellow('###################### 등록 후 사용자 잔고 ###################################'))
  186. b = await token.balanceOf(user1);
  187. bUser1 = Number((1/digit) * Number(b));
  188. b = await token.balanceOf(user2);
  189. bUser2 = Number((1/digit) * Number(b));
  190. console.log(chalk.blue(
  191. `사용자1 잔고 : ${Number(bUser1).toFixed(Number(decimals))}\r\n사용자2 잔고 : ${Number(bUser2).toFixed(Number(decimals))}`
  192. ))
  193. console.log(chalk.bgCyan('###################### 사용자 권한테스트 종료 ###################################'))
  194. console.log(chalk.bgGreenBright('###################### 오퍼레이터 권한테스트 시작 ###################################'))
  195. const newOperatorToken = await token.connect(tobeOperator);
  196. const adminToken = await token.connect(admin);
  197. console.log(chalk.green('###################### 변경전 오퍼레이터 전송시도###################################'))
  198. try {
  199. let r = await newOperatorToken.operatorTransferByPartition(partitions[0],holder,user1,1 * digit,ZeroHash,ZeroHash,{gasLimit: 20000000});
  200. console.log(`txhash1 : ${r.hash}`)
  201. const receipt1 = await r.wait();
  202. console.log(receipt1.hash);
  203. r = await newOperatorToken.operatorTransferByPartition(partitions[0],holder,user2,1 * digit,ZeroHash,ZeroHash,{gasLimit: 20000000});
  204. const receipt2 = await r.wait();
  205. console.log(`txhash2 : ${r.hash}`)
  206. console.log('오퍼레이터 등록 전 토큰전송완료....');
  207. } catch(ex) {
  208. console.log(chalk.red('예정된 오퍼레이터 등록전 전송 에러'));
  209. }
  210. console.log(chalk.yellow('###################### 오퍼레이터 권한 등록 ###################################'))
  211. ret = await adminToken.grantRole( id('OPERATOR_ROLE'),tobeOperator,{ gasLimit: 20000000});
  212. receipt = await ret.wait();
  213. console.log(receipt.status)
  214. console.log(chalk.green('###################### 오퍼레이터 권한등록 후 전송시도###################################'))
  215. try {
  216. let r = await newOperatorToken.operatorTransferByPartition(partitions[0],holder,user1,1 * digit,ZeroHash,ZeroHash,{gasLimit: 20000000});
  217. console.log(`txhash1 : ${r.hash}`)
  218. const receipt1 = await r.wait();
  219. console.log(receipt1.hash);
  220. r = await newOperatorToken.operatorTransferByPartition(partitions[0],holder,user2,1 * digit,ZeroHash,ZeroHash,{gasLimit: 20000000});
  221. const receipt2 = await r.wait();
  222. console.log(`txhash2 : ${r.hash}`)
  223. console.log('오퍼레이터 등록 후 토큰전송완료....');
  224. } catch(ex) {
  225. console.log(chalk.red('권한등록후 에러??????????????'));
  226. }
  227. b = await token.balanceOf(user1);
  228. bUser1 = Number((1/digit) * Number(b));
  229. b = await token.balanceOf(user2);
  230. bUser2 = Number((1/digit) * Number(b));
  231. console.log(chalk.blue(
  232. `사용자1 잔고 : ${Number(bUser1).toFixed(Number(decimals))}\r\n사용자2 잔고 : ${Number(bUser2).toFixed(Number(decimals))}`
  233. ))
  234. console.log(chalk.bgGreenBright('###################### 오퍼레이터 권한테스트 종료 ###################################'))
  235. console.log(chalk.yellow('###################### 테스트권한 클리어 ###################################'));
  236. await token.unKYCtokenHolders([user1, user2]);
  237. ret = await adminToken.revokeRole( id('OPERATOR_ROLE'),tobeOperator,{ gasLimit: 20000000});
  238. await ret.wait();
  239. }
  240. const calc = new Calulator();
  241. const rpcUrl = process.env.RPCURL;
  242. const provider = new JsonRpcProvider(rpcUrl);
  243. setProvider(provider);
  244. const admin = new Wallet('0xc87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3',provider);
  245. const issuer = new Wallet('0x8f2a55949038a9610f50fb23b5883af3b4ecb3c3bb792cbcefbd1542c692be63',provider);
  246. //const signer = issuer;
  247. const holder1 = new Wallet('0xae6ae8e5ccbfb04590405997ee2d52d2b330726137b875053c36d94e974d162f',provider);
  248. const holder2 = new Wallet('0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80',provider);
  249. const user1 = new Wallet('5c7ff82446654833ed4cbd3dc7cca94b114b556def572a5f2f7f29224c757adb',provider);
  250. //0xB22f4c5fA701837dcBd037D60F5d2606050fBbd9
  251. const user2 = new Wallet('509157aeb1308d8ff8db8a3059d4392d92fb66960ef5083eda5a8dcc9118be31',provider);
  252. //0xA59D39340AEF8681248aaB3F71D104897FdF7c84
  253. const newOperator = new Wallet('a0e4679c61e04969499af0c4cdcdc66e9a9f2e3f6cbc17ede9e2137518f8e75d',provider);
  254. //0x1e5Ed00f65556374d7fb2039e2a11aDc64021762
  255. async function main() {
  256. await testSecurity('test003',issuer,newOperator,holder1, user1,user2);
  257. }
  258. main();