eth.call on web3 interface returns null value for contract function returning array of bytes32/strings - solidity

I am trying to run a bidding smart contract on a private blockchain and my smart contract is working on the Remix IDE and the same works on my private chain except for one function [dataOwnedBy()] which is suposed to return an array of bytes32 but returns all zero values in geth console.
I have compiled and deployed my smart contract using truffle.
The function which is not working is : (along with data declaration snippet and other function prototypes)
struct data{
bytes32 data_id;
address bidder;
uint bid;
}
mapping(bytes32=>data) bidInfo;
mapping(address=>data[]) dataOwned; //data owned by each address
address[] dataOwners; //list of address who own data
function Bid(bytes32 data_id) public payable { ... }
function closeBid(bytes32 data_id) public { ... }
function whoOwns(bytes32 _data_id) constant public returns (address){ ... }
function dataOwnedBy(address _addr) constant public returns (bytes32[10]){
uint length = dataOwned[_addr].length;
bytes32[10] memory _idArray;
for (uint i=0;i<length;i++){
_idArray[i] = (dataOwned[_addr][i].data_id);
}
return _idArray;
}
After closing the bid, when I query the above function with the winner's address, it returns array of size 10 bytes32 values, all equal to zero, where it should be returning the data_ids owned by the address.!
Version Information from console
> web3.version.api
"0.20.1"
truffle(development)> version
Truffle v3.4.11 (core: 3.4.11)
Solidity v0.4.15 (solc-js)
This is the console output :
playbid.whoOwns("data_id1")
"0x7d8eb703bd863313325b784ac35017614484f2e7"
playbid.dataOwnedBy("0x7d8eb703bd863313325b784ac35017614484f2e7")
["0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x0000000000000000000000000000000000000000000000000000000000000000"]
Instead the first value of the array should be the hex of "data_id1".
Don't know what is going wrong here, but it works perfectly fine on Remix IDE.
Thanks in advance !

As your code is working OK in remix, there is no problem with the smart contract code. I experienced same issue when I wanted to return some arrays back to my web3j powered java app. I also tested web3js and encountered the same problem. The returned array was broken the same way.
I ended up in serializing and deserializing arrays to strings with a delimiter, both in inputs and outputs.

Related

Unable to compile smart contracts

I am learning the tutorials in 「Mastering Ethereum: Building Smart Contracts and DApps」(O'Reilly)
I copied the following sample code and created a solidity contract(METoken.sol).
Next, I compiled it with the「truffle compile」 command, but it gave me an error.Please assist, thanks
//Error Message
TypeError: The first argument must be of type string or an instance of Buffer, ArrayBuffer, or Array or an Array-like Object. Received undefined
// METoken.sol
pragma solidity ^0.4.21;
import 'openzeppelin-solidity/contracts/token/ERC20/StandardToken.sol';
contract METoken is StandardToken {
string public constant name = 'Mastering Ethereum Token';
string public constant symbol = 'MET'; uint8 public constant decimals = 2; uint constant
_initial_supply = 2100000000;
function METoken() public {
totalSupply_ = _initial_supply;
balances[msg.sender] = _initial_supply;
emit Transfer(address(0), msg.sender, _initial_supply);
}
}
The Standard token was renamed to ERC20.sol in openzeppelin contracts 2.0 version.
You have to modify your imports , then the contract will get compile.
Refer..
https://github.com/OpenZeppelin/openzeppelin-contracts/issues/1557

create2 not working in tron, gives empty bytecode

So, I've a contract which deploys using create2 i.e., custom salt. Its working perfectly in Ethereum but with Tron it's not. When its called, the result of the contract ( which is created by create2 ) is empty. The contract ABI and Bytecode both shows null. I dont know why its happening. Am I missing something?
Here is the part of the code of my contract
function deploy(address _owner, uint256 _salt) public returns (address addr) {
bytes memory bytecode = getBytecode(_owner);
assembly {
addr := create2(
0,
add(bytecode, 0x20),
mload(bytecode),
_salt
)
if iszero(extcodesize(addr)) {
revert(0, 0)
}
}
emit Deployed(addr, _salt);
}
function getBytecode(address _owner) public pure returns (bytes memory) {
bytes memory bytecode = type(Forwarder).creationCode;
return abi.encodePacked(bytecode, abi.encode(_owner));
}
Forwarder is my Contract
This is one of my contract which is deployed by create2
If anyone need anymore info, Let me know.
I wanna solve this.
So, we cannot get ABI and bytecode of a contract deployed using create2 said by tron support team.
and they provided a solution i.e.,
let instance = await tronWeb.contract().at("TREwN2qRkME9TyQUz8dG6HfjEyKGMPHAS5");
instance.loadAbi([{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"}]);
let res = await instance.totalSupply().call({_isConstant:true})
so we can get the instance from contract address and load the ABI
and then we can call the contract function and perform operation.

Is this a remix,compiler or an openzeplin bug?

I just wrote a simple code to test openzeplin Safemath library. I am using the latest version of remix ide and compiling for ^0.5.0.
Remix is using 0.5.0_commit.1d4f565a compiler
The environment is JavaScript VM
EVM Version is the compiler default
The add function does not seem to be working in the code given below
I have tried x.sub(1) it throws an exception as expected, i have also tried initializing x to different values but still does not work.
pragma solidity ^0.5.0;
import "./SafeMath.sol";
contract SimpleStorage {
using SafeMath for uint;
uint x;
event incremented(uint x);
constructor() public{
x=0;
}
function increment() public {
x.add(1);
emit incremented(x);
}
function get() external view returns (uint) {
return x;
}
}
Expected output is an increment by one on every call to the function but getting the same value every time. Emit also shows the same value.
Well, it's your bug :)
Instead of x.add(1) try x = x.add(1). Add function is not inplace, new value is returned and you need to assign the new value to x.

Example Oraclize files return 0: string: when called in Remix

I want to use Oraclize in Remix, to test it. I'm too stupid to use their examples.
How can I make this work?
From their Github I took the YouTube-Views code and copied it into Remix
pragma solidity >= 0.5.0 < 0.6.0;
import "github.com/oraclize/ethereum-api/oraclizeAPI.sol";
contract YoutubeViews is usingOraclize {
string public viewsCount;
event LogYoutubeViewCount(string views);
event LogNewOraclizeQuery(string description);
constructor()
public
{
update(); // Update views on contract creation...
}
function __callback(
bytes32 _myid,
string memory _result
)
public
{
require(msg.sender == oraclize_cbAddress());
viewsCount = _result;
emit LogYoutubeViewCount(viewsCount);
// Do something with viewsCount, like tipping the author if viewsCount > X?
}
function update()
public
payable
{
emit LogNewOraclizeQuery("Oraclize query was sent, standing by for the answer...");
oraclize_query("URL", 'html(https://www.youtube.com/watch?v=9bZkp7q19f0).xpath(//*[contains(#class, "watch-view-count")]/text())');
}
}
When I use the viewCount it returns:
0: string:
This happens with all the other examples aswell.
With WolframAlpha eg. I also get the following error:
transact to WolframAlpha.update errored: VM error: revert.
revert The transaction has been reverted to the initial state.
Note: The constructor should be payable if you send value. Debug the transaction to get more information.
Ok you don't see the answer like a normal result in Remix:
You have to go under settings and open the Oraclize plug in.
If you then deploy the contract and or click update, you get the result shown in the plug in.

Trying to make an array with a variable size in solidity

I am trying to write string to the blockchain using events. This will cost a lot of gas regularly, so I am attempting to compress my strings. They become compressed into a uint8array in js. Here is my solidity script:
pragma solidity ^0.4.18;
contract EthProj {
event Message(uint8[] message, address add, uint256 cost);
event Username(uint8[] name, address add, uint256 cost);
function setMessage(uint8[] _fMessage) public {
uint8[] memory output = new uint8[](_fMessage.length);
output = _fMessage;
emit Message(output, msg.sender, gasleft());
}
function setUsername(uint8[] _userName) public {
emit Username(_userName, msg.sender, gasleft());
}
}
My goal with this is to have the size of the array be dependent on the size of the compressed text, but I get invalid number of arguments error when calling it using this:
message = document.getElementById("MessageBox").value;
compressed = shoco.compress(message);
EthProj.setMessage.sendTransaction(compressed, {from: document.getElementById("add").value});`
Can you not make an array with variable size, and if I can't, than how do I go about achieving my goal? The error is: Invalid number of arguments to solidity function