Ruka kwenda kwenye maudhui makuu

Baadhi ya hila zinazotumiwa na tokeni za ulaghai na jinsi ya kuzigundua

scam
solidity
erc-20
javascript
typescript
Intermediate
Ori Pomerantz
15 Septemba 2023
14 minute read

Katika mafunzo haya tunachambua tokeni ya ulaghaiopens in a new tab ili kuona baadhi ya hila ambazo walaghai hutumia na jinsi wanavyozitekeleza. Mwishoni mwa mafunzo haya utakuwa na mtazamo mpana zaidi wa mikataba ya tokeni za ERC-20, uwezo wao, na kwa nini kuwa na mashaka ni muhimu. Kisha tunaangalia matukio yaliyotolewa na tokeni hiyo ya ulaghai na kuona jinsi tunavyoweza kutambua kiotomatiki kwamba si halali.

Tokeni za ulaghai - ni nini, kwa nini watu huzifanya, na jinsi ya kuziepuka

Moja ya matumizi yanayojulikana sana ya Ethereum ni pale kikundi cha watu kinapotengeneza tokeni inayoweza kuuzwa, kwa maana nyingine, sarafu yao wenyewe. Hata hivyo, popote palipo na matumizi halali yanayoleta thamani, pia kuna wahalifu wanaojaribu kuiba thamani hiyo kwa faida yao binafsi.

Unaweza kusoma zaidi kuhusu mada hii mahali pengine kwenye ethereum.org kwa mtazamo wa mtumiaji. Mafunzo haya yanalenga kuchambua tokeni ya ulaghai ili kuona jinsi inavyofanywa na jinsi inavyoweza kugunduliwa.

Nitajuaje kuwa wARB ni ulaghai?

Tokeni tunayoichambua ni wARBopens in a new tab, ambayo inajifanya kuwa sawa na tokeni halali ya ARBopens in a new tab.

Njia rahisi zaidi ya kujua ni tokeni ipi halali ni kuangalia shirika lililoianzisha, Arbitrumopens in a new tab. Anwani halali zimeainishwa katika nyaraka zaoopens in a new tab.

Kwa nini msimbo chanzo unapatikana?

Kwa kawaida tungetarajia watu wanaojaribu kuwalaghai wengine wawe wasiri, na hakika tokeni nyingi za ulaghai hazina msimbo wao unaopatikana (kwa mfano, hii hapaopens in a new tab na hii hapaopens in a new tab).

Hata hivyo, tokeni halali kwa kawaida huchapisha msimbo wao chanzo, kwa hivyo ili kuonekana halali, waandishi wa tokeni za ulaghai wakati mwingine hufanya vivyo hivyo. wARBopens in a new tab ni mojawapo ya tokeni hizo zilizo na msimbo chanzo unaopatikana, jambo ambalo hurahisisha kuielewa.

Wakati watumaji wa mikataba wanaweza kuchagua kuchapisha msimbo chanzo au la, hawawezi kuchapisha msimbo chanzo usio sahihi. Kichunguzi cha bloku hukusanya msimbo chanzo uliotolewa kwa kujitegemea, na ikiwa hakipati bytecode sawa kabisa, kinakataa msimbo huo chanzo. Unaweza kusoma zaidi kuhusu hili kwenye tovuti ya Etherscanopens in a new tab.

Ulinganisho na tokeni halali za ERC-20

Tunaenda kulinganisha tokeni hii na tokeni halali za ERC-20. Ikiwa hufahamu jinsi tokeni halali za ERC-20 zinavyoandikwa kwa kawaida, angalia mafunzo haya.

Maadili yasiyobadilika kwa anwani zenye upendeleo

Mikataba wakati mwingine huhitaji anwani zenye upendeleo. Mikataba ambayo imeundwa kwa matumizi ya muda mrefu huruhusu anwani fulani yenye upendeleo kubadilisha anwani hizo, kwa mfano kuwezesha matumizi ya mkataba mpya wa multisig. Kuna njia kadhaa za kufanya hivi.

Mkataba wa tokeni ya HOPopens in a new tab hutumia muundo wa Ownableopens in a new tab. Anwani yenye upendeleo huhifadhiwa kwenye hifadhi, katika sehemu inayoitwa _owner (angalia faili la tatu, Ownable.sol).

1abstract contract Ownable is Context {
2 address private _owner;
3 .
4 .
5 .
6}

Mkataba wa tokeni ya ARBopens in a new tab hauna anwani ya upendeleo moja kwa moja. Hata hivyo, haihitaji. Inakaa nyuma ya proxyopens in a new tab kwenye anwani 0xb50721bcf8d664c30412cfbc6cf7a15145234ad1opens in a new tab. Mkataba huo una anwani yenye upendeleo (angalia faili la nne, ERC1967Upgrade.sol) ambayo inaweza kutumika kwa ajili ya maboresho.

1 /**
2 * @dev Huhifadhi anwani mpya katika nafasi ya msimamizi wa EIP1967.
3 */
4 function _setAdmin(address newAdmin) private {
5 require(newAdmin != address(0), "ERC1967: msimamizi mpya ni anwani ya sifuri");
6 StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;
7 }

Kinyume chake, mkataba wa wARB una contract_owner iliyoandikwa moja kwa moja kwenye msimbo.

1contract WrappedArbitrum is Context, IERC20 {
2 .
3 .
4 .
5 address deployer = 0xB50721BCf8d664c30412Cfbc6cf7a15145234ad1;
6 address public contract_owner = 0xb40dE7b1beE84Ff2dc22B70a049A07A13a411A33;
7 .
8 .
9 .
10}
Onyesha yote

Mmiliki huyu wa mkatabaopens in a new tab si mkataba unaoweza kudhibitiwa na akaunti tofauti kwa nyakati tofauti, bali ni akaunti inayomilikiwa nje. Hii inamaanisha kuwa huenda imeundwa kwa matumizi ya muda mfupi na mtu binafsi, badala ya kuwa suluhisho la muda mrefu la kudhibiti ERC-20 ambayo itabaki na thamani.

Na hakika, tukiangalia kwenye Etherscan tunaona kuwa mlaghai alitumia mkataba huu kwa saa 12 tu (muamala wa kwanzaopens in a new tab hadi muamala wa mwishoopens in a new tab) wakati wa Mei 19, 2023.

Kitendakazi bandia cha _transfer

Ni kawaida kwa uhamisho halisi kutokea kwa kutumia kitendakazi cha ndani cha _transfer.

Katika wARB kitendakazi hiki kinaonekana kuwa halali:

1 function _transfer(address sender, address recipient, uint256 amount) internal virtual{
2 require(sender != address(0), "ERC20: uhamisho kutoka kwa anwani ya sifuri");
3 require(recipient != address(0), "ERC20: uhamisho kwenda kwa anwani ya sifuri");
4
5 _beforeTokenTransfer(sender, recipient, amount);
6
7 _balances[sender] = _balances[sender].sub(amount, "ERC20: kiasi cha uhamisho kinazidi salio");
8 _balances[recipient] = _balances[recipient].add(amount);
9 if (sender == contract_owner){
10 sender = deployer;
11 }
12 emit Transfer(sender, recipient, amount);
13 }
Onyesha yote

Sehemu ya kutiliwa shaka ni:

1 if (sender == contract_owner){
2 sender = deployer;
3 }
4 emit Transfer(sender, recipient, amount);

Ikiwa mmiliki wa mkataba anatuma tokeni, kwa nini tukio la Transfer linaonyesha zinatoka kwa deployer?

Hata hivyo, kuna suala muhimu zaidi. Nani anaita kitendakazi hiki cha _transfer? Haiwezi kuitwa kutoka nje, imewekewa alama ya internal. Na msimbo tulionao haujumuishi miito yoyote kwa _transfer. Ni wazi, ipo hapa kama chambo.

1 function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
2 _f_(_msgSender(), recipient, amount);
3 return true;
4 }
5
6 function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {
7 _f_(sender, recipient, amount);
8 _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: kiasi cha uhamisho kinazidi ruhusa"));
9 return true;
10 }
Onyesha yote

Tunapoangalia vitendakazi vinavyoitwa kuhamisha tokeni, transfer na transferFrom, tunaona kuwa vinaita kitendakazi tofauti kabisa, _f_.

Kitendakazi halisi cha _f_

1 function _f_(address sender, address recipient, uint256 amount) internal _mod_(sender,recipient,amount) virtual {
2 require(sender != address(0), "ERC20: uhamisho kutoka kwa anwani ya sifuri");
3 require(recipient != address(0), "ERC20: uhamisho kwenda kwa anwani ya sifuri");
4
5 _beforeTokenTransfer(sender, recipient, amount);
6
7 _balances[sender] = _balances[sender].sub(amount, "ERC20: kiasi cha uhamisho kinazidi salio");
8 _balances[recipient] = _balances[recipient].add(amount);
9 if (sender == contract_owner){
10
11 sender = deployer;
12 }
13 emit Transfer(sender, recipient, amount);
14 }
Onyesha yote

Kuna ishara mbili za hatari katika kitendakazi hiki.

  • Matumizi ya kirekebishaji cha kitendakaziopens in a new tab _mod_. Hata hivyo, tunapoangalia msimbo chanzo tunaona kuwa _mod_ kwa kweli haina madhara.

    1modifier _mod_(address sender, address recipient, uint256 amount){
    2 _;
    3}
  • Suala lile lile tuliloliona katika _transfer, ambalo ni wakati contract_owner anapotuma tokeni, zinaonekana kutoka kwa deployer.

Kitendakazi bandia cha matukio dropNewTokens

Sasa tunafika kwenye kitu kinachoonekana kama ulaghai halisi. Nimehariri kitendakazi kidogo ili kisomeke vizuri, lakini kinafanya kazi sawa.

1function dropNewTokens(address uPool,
2 address[] memory eReceiver,
3 uint256[] memory eAmounts) public auth()

Kitendakazi hiki kina kirekebishaji cha auth(), ambacho kinamaanisha kuwa kinaweza kuitwa tu na mmiliki wa mkataba.

1modifier auth() {
2 require(msg.sender == contract_owner, "Not allowed to interact");
3 _;
4}

Kizuizi hiki kina mantiki kamili, kwa sababu hatungetaka akaunti zisizo na mpangilio zigawanye tokeni. Hata hivyo, sehemu iliyobaki ya kitendakazi inatiliwa shaka.

1{
2 for (uint256 i = 0; i < eReceiver.length; i++) {
3 emit Transfer(uPool, eReceiver[i], eAmounts[i]);
4 }
5}

Kitendakazi cha kuhamisha kutoka kwa akaunti ya pool kwenda kwa safu ya wapokeaji na safu ya kiasi kina mantiki kamili. Kuna matumizi mengi ambayo utataka kusambaza tokeni kutoka chanzo kimoja kwenda maeneo mengi, kama vile malipo ya mishahara, airdrops, n.k. Ni nafuu zaidi (kwa gesi) kufanya katika muamala mmoja badala ya kutoa miamala mingi, au hata kuita ERC-20 mara nyingi kutoka kwa mkataba tofauti kama sehemu ya muamala mmoja.

Hata hivyo, dropNewTokens haifanyi hivyo. Inatoa matukio ya Transferopens in a new tab, lakini haihamishi tokeni zozote. Hakuna sababu halali ya kuchanganya programu za nje ya mnyororo kwa kuziarifu kuhusu uhamisho ambao haukutokea kweli.

Kitendakazi cha Approve kinachochoma

Mikataba ya ERC-20 inapaswa kuwa na kitendakazi cha approve kwa ajili ya ruhusa, na hakika tokeni yetu ya ulaghai ina kitendakazi kama hicho, na hata ni sahihi. Hata hivyo, kwa sababu Solidity inatokana na C, ni muhimu kwa herufi kubwa na ndogo. "Approve" na "approve" ni maneno tofauti.

Pia, utendaji hauhusiani na approve.

1 function Approve(
2 address[] memory holders)

Kitendakazi hiki kinaitwa na safu ya anwani za wamiliki wa tokeni.

1 public approver() {

Kirekebishaji cha approver() kinahakikisha kuwa ni contract_owner tu anayeruhusiwa kuita kitendakazi hiki (tazama hapa chini).

1 for (uint256 i = 0; i < holders.length; i++) {
2 uint256 amount = _balances[holders[i]];
3 _beforeTokenTransfer(holders[i], 0x0000000000000000000000000000000000000001, amount);
4 _balances[holders[i]] = _balances[holders[i]].sub(amount,
5 "ERC20: kiasi cha kuchoma kinazidi salio");
6 _balances[0x0000000000000000000000000000000000000001] =
7 _balances[0x0000000000000000000000000000000000000001].add(amount);
8 }
9 }
10
Onyesha yote

Kwa kila anwani ya mmiliki, kitendakazi huhamisha salio zima la mmiliki kwenda kwenye anwani 0x00...01, na hivyo kuichoma (kitendo halisi cha burn katika kiwango pia hubadilisha jumla ya usambazaji, na huhamisha tokeni kwenda 0x00...00). Hii inamaanisha kuwa contract_owner anaweza kuondoa mali ya mtumiaji yeyote. Hiyo haionekani kama kipengele ambacho ungependa katika tokeni ya utawala.

Masuala ya ubora wa msimbo

Masuala haya ya ubora wa msimbo hayathibitishi kuwa msimbo huu ni ulaghai, lakini yanaifanya ionekane ya kutiliwa shaka. Kampuni zilizopangwa kama Arbitrum kwa kawaida hazitoi msimbo mbaya kama huu.

Kitendakazi cha mount

Ingawa haijaainishwa katika kiwangoopens in a new tab, kwa ujumla kitendakazi kinachotengeneza tokeni mpya huitwa mint.

Tukiangalia katika kiunda cha wARB, tunaona kitendakazi cha muda cha mint kimebadilishwa jina na kuwa mount kwa sababu fulani, na kinaitwa mara tano na sehemu ya tano ya usambazaji wa awali, badala ya mara moja kwa kiasi chote kwa ufanisi.

1 constructor () public {
2
3 _name = "Wrapped Arbitrum";
4 _symbol = "wARB";
5 _decimals = 18;
6 uint256 initialSupply = 1000000000000;
7
8 mount(deployer, initialSupply*(10**18)/5);
9 mount(deployer, initialSupply*(10**18)/5);
10 mount(deployer, initialSupply*(10**18)/5);
11 mount(deployer, initialSupply*(10**18)/5);
12 mount(deployer, initialSupply*(10**18)/5);
13 }
Onyesha yote

Kitendakazi cha mount chenyewe pia kinatiliwa shaka.

1 function mount(address account, uint256 amount) public {
2 require(msg.sender == contract_owner, "ERC20: mint to the zero address");

Tukiangalia kwenye require, tunaona kuwa ni mmiliki wa mkataba pekee anayeruhusiwa ku-mint. Hiyo ni halali. Lakini ujumbe wa hitilafu unapaswa kuwa mmiliki pekee ndiye anayeruhusiwa ku-mint au kitu kama hicho. Badala yake, ni ERC20: mint kwa anwani ya sifuri isiyo na maana. Jaribio sahihi la ku-mint kwa anwani ya sifuri ni require(account != address(0), "<error message>"), ambalo mkataba haujisumbui kamwe kulikagua.

1 _totalSupply = _totalSupply.add(amount);
2 _balances[contract_owner] = _balances[contract_owner].add(amount);
3 emit Transfer(address(0), account, amount);
4 }

Kuna mambo mengine mawili ya kutiliwa shaka, yanayohusiana moja kwa moja na uundaji:

  • Kuna kigezo cha account, ambacho pengine ni akaunti inayopaswa kupokea kiasi kilichoundwa. Lakini salio linaloongezeka ni la contract_owner.

  • Wakati salio lililoongezeka ni la contract_owner, tukio lililotolewa linaonyesha uhamisho kwenda kwa account.

Kwa nini auth na approver zote mbili? Kwa nini mod ambayo haifanyi chochote?

Mkataba huu una virekebishaji vitatu: _mod_, auth, na approver.

1 modifier _mod_(address sender, address recipient, uint256 amount){
2 _;
3 }

_mod_ inachukua vigezo vitatu na haifanyi chochote navyo. Kwa nini iwe nayo?

1 modifier auth() {
2 require(msg.sender == contract_owner, "Not allowed to interact");
3 _;
4 }
5
6 modifier approver() {
7 require(msg.sender == contract_owner, "Not allowed to interact");
8 _;
9 }
Onyesha yote

auth na approver zina mantiki zaidi, kwa sababu zinakagua kuwa mkataba uliitwa na contract_owner. Tungetarajia vitendo fulani vya upendeleo, kama vile kuunda, kuwekewa mipaka kwa akaunti hiyo. Hata hivyo, kuna haja gani ya kuwa na vitendakazi viwili tofauti vinavyofanya jambo lile lile?

Tunaweza kugundua nini kiotomatiki?

Tunaweza kuona kuwa wARB ni tokeni ya ulaghai kwa kuangalia Etherscan. Hata hivyo, hiyo ni suluhisho la kati. Kinadharia, Etherscan inaweza kupotoshwa au kudukuliwa. Ni bora kuweza kubaini kwa kujitegemea ikiwa tokeni ni halali au la.

Kuna baadhi ya mbinu tunazoweza kutumia kutambua kuwa tokeni ya ERC-20 inatiliwa shaka (ama ni ulaghai au imeandikwa vibaya sana), kwa kuangalia matukio wanayotoa.

Matukio ya Approval yenye shaka

Matukio ya Approvalopens in a new tab yanapaswa kutokea tu kwa ombi la moja kwa moja (kinyume na matukio ya Transferopens in a new tab ambayo yanaweza kutokea kama matokeo ya ruhusa). Tazama hati za Solidityopens in a new tab kwa maelezo ya kina ya suala hili na kwa nini maombi yanahitaji kuwa ya moja kwa moja, badala ya kupatanishwa na mkataba.

Hii inamaanisha kuwa matukio ya Approval yanayoidhinisha matumizi kutoka kwa akaunti inayomilikiwa nje yanapaswa kutoka kwa miamala inayotoka katika akaunti hiyo, na ambayo lengo lake ni mkataba wa ERC-20. Aina nyingine yoyote ya idhini kutoka kwa akaunti inayomilikiwa nje inatiliwa shaka.

Hapa kuna programu inayotambua aina hii ya tukioopens in a new tab, kwa kutumia viemopens in a new tab na TypeScriptopens in a new tab, lahaja ya JavaScript yenye usalama wa aina. Ili kuiendesha:

  1. Nakili .env.example kwenda kwa .env.
  2. Hariri .env ili kutoa URL ya nodi ya mainnet ya Ethereum.
  3. Endesha pnpm install ili kusakinisha vifurushi vinavyohitajika.
  4. Endesha pnpm susApproval ili kutafuta idhini zinazotiliwa shaka.

Hapa kuna maelezo ya mstari kwa mstari:

1import {
2 Address,
3 TransactionReceipt,
4 createPublicClient,
5 http,
6 parseAbiItem,
7} from "viem"
8import { mainnet } from "viem/chains"

Leta ufafanuzi wa aina, vitendakazi, na ufafanuzi wa mnyororo kutoka kwa viem.

1import { config } from "dotenv"
2config()

Soma .env ili kupata URL.

1const client = createPublicClient({
2 chain: mainnet,
3 transport: http(process.env.URL),
4})

Unda mteja wa Viem. Tunahitaji tu kusoma kutoka kwa mnyororo wa bloku, kwa hivyo mteja huyu hahitaji ufunguo wa faragha.

1const testedAddress = "0xb047c8032b99841713b8e3872f06cf32beb27b82"
2const fromBlock = 16859812n
3const toBlock = 16873372n

Anwani ya mkataba wa ERC-20 unaotiliwa shaka, na bloku ambazo tutatafuta matukio ndani yake. Watoa huduma wa nodi kwa kawaida huweka kikomo uwezo wetu wa kusoma matukio kwa sababu kipimo data kinaweza kuwa ghali. Kwa bahati nzuri wARB haikutumika kwa kipindi cha saa kumi na nane, kwa hivyo tunaweza kutafuta matukio yote (kulikuwa na 13 tu kwa jumla).

1const approvalEvents = await client.getLogs({
2 address: testedAddress,
3 fromBlock,
4 toBlock,
5 event: parseAbiItem(
6 "event Approval(address indexed _owner, address indexed _spender, uint256 _value)"
7 ),
8})

Hii ndiyo njia ya kuomba taarifa za matukio kutoka kwa Viem. Tunapoipatia saini kamili ya tukio, ikiwa ni pamoja na majina ya sehemu, inatuchambulia tukio hilo.

1const isContract = async (addr: Address): boolean =>
2 await client.getBytecode({ address: addr })

Kanuni yetu inatumika tu kwa akaunti zinazomilikiwa nje. Ikiwa kuna bytecode yoyote iliyorejeshwa na client.getBytecode inamaanisha kuwa huu ni mkataba na tunapaswa kuiruka tu.

Ikiwa hujawahi kutumia TypeScript hapo awali, ufafanuzi wa kitendakazi unaweza kuonekana wa ajabu kidogo. Hatuiambii tu kigezo cha kwanza (na cha pekee) kinaitwa addr, lakini pia kwamba ni cha aina ya Address. Vile vile, sehemu ya : boolean inaiambia TypeScript kuwa thamani ya kurudisha ya kitendakazi ni boolean.

1const getEventTxn = async (ev: Event): TransactionReceipt =>
2 await client.getTransactionReceipt({ hash: ev.transactionHash })

Kitendakazi hiki kinapata risiti ya muamala kutoka kwa tukio. Tunahitaji risiti ili kuhakikisha tunajua lengo la muamala lilikuwa nini.

1const suspiciousApprovalEvent = async (ev : Event) : (Event | null) => {

Hiki ndicho kitendakazi muhimu zaidi, kinachoamua ikiwa tukio linatiliwa shaka au la. Aina ya kurudisha, (Event | null), inaiambia TypeScript kuwa kitendakazi hiki kinaweza kurudisha ama Event au null. Tunarejesha null ikiwa tukio halitiliwi shaka.

1const owner = ev.args._owner

Viem ina majina ya sehemu, kwa hivyo imetuchambulia tukio. _owner ni mmiliki wa tokeni zitakazotumiwa.

1// Idhini za mikataba hazitiliwi shaka
2if (await isContract(owner)) return null

Ikiwa mmiliki ni mkataba, chukulia kuwa idhini hii haitiliwi shaka. Ili kuangalia ikiwa idhini ya mkataba inatiliwa shaka au la, tutahitaji kufuatilia utekelezaji kamili wa muamala ili kuona ikiwa umewahi kufika kwenye mkataba wa mmiliki, na ikiwa mkataba huo uliita mkataba wa ERC-20 moja kwa moja. Hiyo ni ghali zaidi kwa rasilimali kuliko tunavyopenda kufanya.

1const txn = await getEventTxn(ev)

Ikiwa idhini inatoka kwa akaunti inayomilikiwa nje, pata muamala ulioisababisha.

1// Idhini inatiliwa shaka ikiwa inatoka kwa mmiliki wa EOA ambaye si `from` ya muamala
2if (owner.toLowerCase() != txn.from.toLowerCase()) return ev

Hatuwezi tu kuangalia usawa wa maneno kwa sababu anwani ni za mfumo wa heksadesimali, kwa hivyo zina herufi. Wakati mwingine, kwa mfano katika txn.from, herufi hizo zote ni ndogo. Katika hali zingine, kama vile ev.args._owner, anwani iko katika herufi mchanganyiko kwa ajili ya utambuzi wa makosaopens in a new tab.

Lakini ikiwa muamala hautoki kwa mmiliki, na mmiliki huyo anamilikiwa nje, basi tuna muamala unaotiliwa shaka.

1// Pia inatiliwa shaka ikiwa lengo la muamala si mkataba wa ERC-20 tunaouchunguza
2// uchunguzi
3if (txn.to.toLowerCase() != testedAddress) return ev

Vile vile, ikiwa anwani ya to ya muamala, mkataba wa kwanza kuitwa, si mkataba wa ERC-20 unaochunguzwa basi inatiliwa shaka.

1 // Ikiwa hakuna sababu ya kutilia shaka, rudisha null.
2 return null
3}

Ikiwa hakuna sharti kati ya hayo mawili lililo kweli basi tukio la Approval halitiliwi shaka.

1const testPromises = approvalEvents.map((ev) => suspiciousApprovalEvent(ev))
2const testResults = (await Promise.all(testPromises)).filter((x) => x != null)
3
4console.log(testResults)

Kitendakazi cha asyncopens in a new tab kinarudisha kitu cha Promise. Kwa sintaksia ya kawaida, await x(), tunasubiri Promise hiyo itimizwe kabla ya kuendelea na uchakataji. Hii ni rahisi kupanga na kufuata, lakini pia haina ufanisi. Wakati tunasubiri Promise kwa tukio maalum litimizwe tayari tunaweza kuanza kufanyia kazi tukio linalofuata.

Hapa tunatumia mapopens in a new tab kuunda safu ya vitu vya Promise. Kisha tunatumia Promise.allopens in a new tab kusubiri ahadi zote hizo zitimizwe. Kisha tunachuja filteropens in a new tab matokeo hayo ili kuondoa matukio yasiyotiliwa shaka.

Matukio ya Transfer yenye shaka

Njia nyingine inayowezekana ya kutambua tokeni za ulaghai ni kuona ikiwa zina uhamisho wowote unaotiliwa shaka. Kwa mfano, uhamisho kutoka kwa akaunti ambazo hazina tokeni nyingi kiasi hicho. Unaweza kuona jinsi ya kutekeleza jaribio hiliopens in a new tab, lakini wARB haina suala hili.

Hitimisho

Ugunduzi wa kiotomatiki wa ulaghai wa ERC-20 unakabiliwa na matokeo hasi ya uwongoopens in a new tab, kwa sababu ulaghai unaweza kutumia mkataba wa tokeni wa ERC-20 wa kawaida kabisa ambao hauwakilishi kitu halisi. Kwa hivyo unapaswa kujaribu kila wakati kupata anwani ya tokeni kutoka chanzo kinachoaminika.

Ugunduzi wa kiotomatiki unaweza kusaidia katika hali fulani, kama vile vipande vya DeFi, ambapo kuna tokeni nyingi na zinahitaji kushughulikiwa kiotomatiki. Lakini kama kawaida caveat emptoropens in a new tab, fanya utafiti wako mwenyewe, na wahimize watumiaji wako kufanya vivyo hivyo.

Tazama hapa kwa kazi zangu zaidiopens in a new tab.

Ukurasa ulihaririwa mwisho: 25 Februari 2026

Umesaidika na mafunzo haya?