web3p / web3.php

A php interface for interacting with the Ethereum blockchain and ecosystem. Native ABI parsing and smart contract interactions.
MIT License
1.17k stars 550 forks source link

How interact with smart contract using web3.php #248

Open vnxz opened 2 years ago

vnxz commented 2 years ago

I try to interact with smart contract in laravel using web3.php.


$abi = "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"balances\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]" ;
$contract = new Contract('http://localhost:8545', $abi);
//dd($contract);

$contractAddress = '0x4A789dE2fE1926A6428000c094Bc81a46F15e3E0';

$toaddress = '0xeE01EDe04D42e1a51C99f2737B9E14Fc930a1fd4';
$amount = 100 ;
    // call contract function
$contract->at($contractAddress)

         ->call('transfer', $toaddress, $amount , function ($err, $data) {
                if ($err !== null) {
                  throw new Exception($err->getMessage());
                }
                dd($data);
              });

   }

my contract is

 *Submitted for verification at BscScan.com on 2022-02-04
*/

// SPDX-License-Identifier: GPL-3.0

pragma solidity ^0.8.2;

contract Token {
    mapping(address => uint) public balances;
    mapping(address => mapping(address => uint)) public allowance;
    uint public totalSupply = 10000 * 10 ** 18;
    string public name = "My Token";
    string public symbol = "TKN";
    uint public decimals = 18;

    event Transfer(address indexed from, address indexed to, uint value);
    event Approval(address indexed owner, address indexed spender, uint value);

    constructor() {
        balances[msg.sender] = totalSupply;
    }

    function balanceOf(address owner) public view returns(uint) {
        return balances[owner];
    }

    function transfer(address to, uint value) public returns(bool) {
        require(balanceOf(msg.sender) >= value, 'balance too low');
        balances[to] += value;
        balances[msg.sender] -= value;
       emit Transfer(msg.sender, to, value);
        return true;
    }

    function transferFrom(address from, address to, uint value) public returns(bool) {
        require(balanceOf(from) >= value, 'balance too low');
        require(allowance[from][msg.sender] >= value, 'allowance too low');
        balances[to] += value;
        balances[from] -= value;
        emit Transfer(from, to, value);
        return true;   
    }

    function approve(address spender, uint value) public returns (bool) {
        allowance[msg.sender][spender] = value;
        emit Approval(msg.sender, spender, value);
        return true;   
    }
}

error is

cURL error 28: Failed to connect to localhost port 8545: Timed out (see https://curl.haxx.se/libcurl/c/libcurl-errors.html) for http://localhost:8545 

why this happen? plz someone help

MariusMez commented 2 years ago

It seems your contract is deployed to the BSC, so you need a provider on that blockchain.

localhost:8545 is a local address in cas you use a local node (hardhat, truffle, ganache, ...)

You need to use a provider uri for that blockchain (see: https://docs.binance.org/smart-chain/developer/create-wallet.html#connect-to-bsc-network)

Something like this to connect to the BSC mainnet :

$contract = new Contract('https://bsc-dataseed1.binance.org:443', $abi);

An other example for the BSC testnet and with a timeout for the provider (default is 1s and this is short sometimes):

$providerUri='https://data-seed-prebsc-1-s1.binance.org:8545';
$timeout = 30;
$provider = new HttpProvider(new HttpRequestManager($providerUri, $timeout));
$contract = new Contract($provider, $abi)
vnxz commented 2 years ago

It seems your contract is deployed to the BSC, so you need a provider on that blockchain.

localhost:8545 is a local address in cas you use a local node (hardhat, truffle, ganache, ...)

You need to use a provider uri for that blockchain (see: https://docs.binance.org/smart-chain/developer/create-wallet.html#connect-to-bsc-network)

Something like this to connect to the BSC mainnet :

$contract = new Contract('https://bsc-dataseed1.binance.org:443', $abi);

An other example for the BSC testnet and with a timeout for the provider (default is 1s and this is short sometimes):

$providerUri='https://data-seed-prebsc-1-s1.binance.org:8545';
$timeout = 30;
$provider = new HttpProvider(new HttpRequestManager($providerUri, $timeout));
$contract = new Contract($provider, $abi)

thanks bro, can you also show me process of sending token in web3.php. it need to sign in transaction first and then send token. cannot call directly transfer method . do you have some example for this . I try to send token on web3.php by laravel.

MariusMez commented 2 years ago

Please see my response here: https://github.com/web3p/web3.php/issues/251#issuecomment-1063884215

banls commented 2 years ago

Thinks