Skip to content

daog1/ethers.js

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

The Ethers Project

ethers.js修改版,支持函数签名替换,也就是有些人需要的没有abi想调用别人函数的功能。

代码需要重新编译ethers.js,请熟练掌握 npm link用法。 python web3py版在这里

如需,web3.0客户端定制可以联系我,各种语言均可,提供定制。 智能合约代码分析,也可以联系。

修改代码位置: packages\contracts\src.ts\index.ts

async function populateTransaction(contract: Contract, fragment: FunctionFragment, args: Array<any>): Promise<PopulatedTransaction> {

    // If an extra argument is given, it is overrides
    var fnSignature = null;
    let overrides: CallOverrides = {};
    if (args.length === fragment.inputs.length + 1 && typeof (args[args.length - 1]) === "object") {
        overrides = shallowCopy(args.pop());
    } else if (args.length === fragment.inputs.length + 1 && typeof (args[args.length - 1]) === "string") {
        fnSignature = args.pop();
    }

    // Make sure the parameter count matches
    logger.checkArgumentCount(args.length, fragment.inputs.length, "passed to contract");

    // Populate "from" override (allow promises)
    if (contract.signer) {
        if (overrides.from) {
            // Contracts with a Signer are from the Signer's frame-of-reference;
            // but we allow overriding "from" if it matches the signer
            overrides.from = resolveProperties({
                override: resolveName(contract.signer, overrides.from),
                signer: contract.signer.getAddress()
            }).then(async (check) => {
                if (getAddress(check.signer) !== check.override) {
                    logger.throwError("Contract with a Signer cannot override from", Logger.errors.UNSUPPORTED_OPERATION, {
                        operation: "overrides.from"
                    });
                }
                return check.override;
            });
        } else {
            overrides.from = contract.signer.getAddress();
        }

    } else if (overrides.from) {
        overrides.from = resolveName(contract.provider, overrides.from);

        //} else {
        // Contracts without a signer can override "from", and if
        // unspecified the zero address is used
        //overrides.from = AddressZero;
    }

    // Wait for all dependencies to be resolved (prefer the signer over the provider)
    const resolved = await resolveProperties({
        args: resolveAddresses(contract.signer || contract.provider, args, fragment.inputs),
        address: contract.resolvedAddress,
        overrides: (resolveProperties(overrides) || {})
    });

    // The ABI coded transaction
    var data = null;
    if (fnSignature) {
        data = contract.interface.encodeFunctionDataSign(fragment, resolved.args, fnSignature);
    } else {
        data = contract.interface.encodeFunctionData(fragment, resolved.args);
    }
    const tx: PopulatedTransaction = {
        data: data,
        to: resolved.address
    };

    // Resolved Overrides
    const ro = resolved.overrides;

    // Populate simple overrides
    if (ro.nonce != null) { tx.nonce = BigNumber.from(ro.nonce).toNumber(); }
    if (ro.gasLimit != null) { tx.gasLimit = BigNumber.from(ro.gasLimit); }
    if (ro.gasPrice != null) { tx.gasPrice = BigNumber.from(ro.gasPrice); }
    if (ro.from != null) { tx.from = ro.from; }

    // If there was no "gasLimit" override, but the ABI specifies a default, use it
    if (tx.gasLimit == null && fragment.gas != null) {
        tx.gasLimit = BigNumber.from(fragment.gas).add(21000);
    }

    // Populate "value" override
    if (ro.value) {
        const roValue = BigNumber.from(ro.value);
        if (!roValue.isZero() && !fragment.payable) {
            logger.throwError("non-payable method cannot override value", Logger.errors.UNSUPPORTED_OPERATION, {
                operation: "overrides.value",
                value: overrides.value
            });
        }
        tx.value = roValue;
    }

    // Remvoe the overrides
    delete overrides.nonce;
    delete overrides.gasLimit;
    delete overrides.gasPrice;
    delete overrides.from;
    delete overrides.value;

    // Make sure there are no stray overrides, which may indicate a
    // typo or using an unsupported key.
    const leftovers = Object.keys(overrides).filter((key) => ((<any>overrides)[key] != null));
    if (leftovers.length) {
        logger.throwError(`cannot override ${leftovers.map((l) => JSON.stringify(l)).join(",")}`, Logger.errors.UNSUPPORTED_OPERATION, {
            operation: "overrides",
            overrides: leftovers
        });
    }

    return tx;
}

在abi interface内增加encodeFunctionDataSign 函数 修改位置: packages\abi\src.ts\interface.ts

    encodeFunctionDataSign(functionFragment: FunctionFragment | string, values?: Array<any>, fnSign?: string): string {
        if (typeof (functionFragment) === "string") {
            functionFragment = this.getFunction(functionFragment);
        }
        var sighash = null
        if (fnSign != null) {
            sighash = fnSign;
        } else {
            sighash = this.getSighash(functionFragment);
        }

        return hexlify(concat([
            sighash,
            this._encodeParams(functionFragment.inputs, values || [])
        ]));
    }

如觉得有点用处请支持ether.js 无abi调用合约函数,关键代码

开源的已经是全部代码,集市上的在ethers.js 5.0.0的基础上修改,

这个版本在ethers.js master版本上进行。

About

ethers.js no abi call contract function

Resources

License

Security policy

Stars

Watchers

Forks

Packages

No packages published

Languages

  • TypeScript 79.4%
  • JavaScript 18.2%
  • Python 0.6%
  • Java 0.4%
  • Yacc 0.4%
  • Objective-C 0.3%
  • Other 0.7%