6

I am using Solidity Browser to deploy a contract due to from Library contract method failing #2831 issue. On this following answer https://ethereum.stackexchange.com/a/9181/4575 I have guided to use Solidity Browser as (Please note that this solution works.):

I connected Solidity Browser to my local private node by clicking on the block icon and selecting Web3 Provider. I then clicked on Create to deploy the contract above to the blockchain.

I am using Solidity Browser on my server, and it is difficult to do this process using a graphical user interface, due to my ssh connection.

[Q] Is it possible to deploy a contract without using graphical user interface via Solidity Browser? or is there any other solution?

Thank you for your valuable time and help.

  • 2
    Use the right tool for the job. Browser solidity is a great development environment, but it doesn't make any sense to use it without a GUI. If you want to compile on a remote sever, use solc. – Tjaden Hess Jan 1 '17 at 19:39
  • I was using solc all the time but I face with the problem I mention on my first sentences (You can reach the question here: ethereum.stackexchange.com/q/9178/4575) and Solidity Browser allow me to fix this problem. Is there anyway to over come this problem on solc? – alper Jan 2 '17 at 2:43
  • 1
    By using solc compiler can I deploy contracts to my private blockchain network? @TjadenHess – alper Jan 2 '17 at 12:22
  • you can use mist wallet as well to deploy your contracts. – Himanshu Pandey Jan 2 '17 at 19:58
  • @HimanshuPandey It doesn't solve the problem, it's another GUI basically. – Teleporting Goat Jan 3 '17 at 14:58
4

Summary

To deploy your library and contract code using geth, you will have to:

  1. Deploy your LinkedList library code and note the address it is deployed to.

  2. Replace the __LinkedList___...___ text in your Array code with the LinkedLibrary deployment address and deploy the code.

Some other alternatives:

  1. Create an SSH tunnel between your remote server and your local machine so you can access your remote server's geth RPC port from your local machine. Then use Browser Solidity on your local machine to connect to your local machine port which is a proxy for your remote server's geth RPC port - see How can I expose Geth's RPC server to external connections?

  2. Set up your local machine's geth instance to be a peer to your remote server's geth instance. You can then use Browser Solidity to interact with your local machine's geth instance and your actions will be mirrored on your remote server. See Losing connection between nodes on private network and search for private network on this site.



Update With Source Code Provided In Comments Below

Here is the source code from the link below, unaltered except for the pragma statement and the addition of constant to the test_callstack() function:

library LinkedList {
  uint80 constant None = uint80(0); // NULL.

  struct data {
    uint256 head;
    Node[100]  n;
    uint    size;
    uint    insert_number;
    uint    buffer_size;
  }

  struct Node {
    string  data;
    address owner;
    uint    own;
    uint    prev;
    uint    next;
  }

  function construct_me(data storage self){
    self.n[0].own      = 0;
    self.n[0].next     = 0;
    self.n[0].prev     = 0;
    self.head          = 0;

    self.insert_number = self.size = 1;

    self.buffer_size   = 100;
  }
}

contract owned {
  address  public owner;
  function owned() {
    owner = msg.sender;
  }
  function ownerOnly() {
    if (msg.sender != owner) throw;
  }
  modifier onlyOwner {
     if (msg.sender != owner) throw;
          _;
  }
  function transferOwnership(address newOwner) onlyOwner {
    owner = newOwner;
  }
}

contract Array is owned {
  using LinkedList for LinkedList.data;
  using LinkedList for LinkedList.Node;
  LinkedList.data list;

  function Array(){
    if( test_callstack() != 1 ) throw;
    list.construct_me();
  }

  function test_callstack() constant returns ( int ){ return 1; }
}

I've saved the source code above into Contract.sol.

I use the following statement to assign the flattened source code to a variable (reference https://ethereum.stackexchange.com/a/2610/1268):

Iota:DeployLibrary user$ echo "var myContractSource='`$HOME/bin/stripCrLf Contract.sol`'"
var myContractSource="library LinkedList { uint80 constant None = uint80(0);  struct data { uint256 head;  Node[100] n;  uint size; uint insert_number; uint buffer_size; } struct Node { string data;  address owner;  uint own;  uint prev; uint next;  } function construct_me(data storage self){  self.n[0].own = 0; self.n[0].next = 0; self.n[0].prev = 0; self.head = 0; self.insert_number = self.size = 1;  self.buffer_size = 100; }}contract owned {  address public owner; function owned() { owner = msg.sender; } function ownerOnly() { if (msg.sender != owner) throw; } modifier onlyOwner { if (msg.sender != owner) throw; _; } function transferOwnership(address newOwner) onlyOwner { owner = newOwner; }}contract Array is owned { using LinkedList for LinkedList.data; using LinkedList for LinkedList.Node; LinkedList.data list; function Array(){  if( test_callstack() != 1 ) throw;  list.construct_me(); } function test_callstack() constant returns ( int ){ return 1; }}"

I copied the line above into my clipboard and pasted it into a --dev geth instance:

> var myContractSource="library LinkedList { uint80 constant None = uint80(0);  struct data { uint256 head;  Node[100] n;  uint size; uint insert_number; uint buffer_size; } struct Node { string data;  address owner;  uint own;  uint prev; uint next;  } function construct_me(data storage self){  self.n[0].own = 0; self.n[0].next = 0; self.n[0].prev = 0; self.head = 0; self.insert_number = self.size = 1;  self.buffer_size = 100; }}contract owned {  address public owner; function owned() { owner = msg.sender; } function ownerOnly() { if (msg.sender != owner) throw; } modifier onlyOwner { if (msg.sender != owner) throw; _; } function transferOwnership(address newOwner) onlyOwner { owner = newOwner; }}contract Array is owned { using LinkedList for LinkedList.data; using LinkedList for LinkedList.Node; LinkedList.data list; function Array(){  if( test_callstack() != 1 ) throw;  list.construct_me(); } function test_callstack() constant returns ( int ){ return 1; }}"
undefined

I compiled the source code:

> var myContractCompiled=web3.eth.compile.solidity(myContractSource);
undefined

To check the available ABIs, I type the following:

> myContractCompiled
myContractCompiled
{
  Array: {
    code: "0x6060604081905260008054600160a060020a0319166c01000000000000000000000000338102041781557f14ea1cf8000000000000000000000000000000000000000000000000000000008252600160645273__LinkedList____________________________916314ea1cf89160849160248186803b1560025760325a03f41560025750505060fd806100936000396000f3606060405260e060020a60003504631309238c8114603a578063896f40dd1460525780638da5cb5b146071578063f2fde38b146086575b6002565b34600257600160408051918252519081900360200190f35b3460025760a860005433600160a060020a0390811691161460c6576002565b3460025760aa600054600160a060020a031681565b3460025760a860043560005433600160a060020a0390811691161460c8576002565b005b60408051600160a060020a039092168252519081900360200190f35b565b600080546c010000000000000000000000008084020473ffffffffffffffffffffffffffffffffffffffff199091161790555056",
    info: {
      abiDefinition: [{...}, {...}, {...}, {...}, {...}],
      compilerOptions: "--combined-json bin,abi,userdoc,devdoc --add-std --optimize",
      compilerVersion: "0.4.4",
      developerDoc: {
        methods: {}
      },
      language: "Solidity",
      languageVersion: "0.4.4",
      source: "library LinkedList { uint80 constant None = uint80(0);  struct data { uint256 head;  Node[100] n;  uint size; uint insert_number; uint buffer_size; } struct Node { string data;  address owner;  uint own;  uint prev; uint next;  } function construct_me(data storage self){  self.n[0].own = 0; self.n[0].next = 0; self.n[0].prev = 0; self.head = 0; self.insert_number = self.size = 1;  self.buffer_size = 100; }}contract owned {  address public owner; function owned() { owner = msg.sender; } function ownerOnly() { if (msg.sender != owner) throw; } modifier onlyOwner { if (msg.sender != owner) throw; _; } function transferOwnership(address newOwner) onlyOwner { owner = newOwner; }}contract Array is owned { using LinkedList for LinkedList.data; using LinkedList for LinkedList.Node; LinkedList.data list; function Array(){  if( test_callstack() != 1 ) throw;  list.construct_me(); } function test_callstack() constant returns ( int ){ return 1; }}",
      userDoc: {
        methods: {}
      }
    }
  },
  LinkedList: {
    code: "0x6060604052605c8060106000396000f36504044633f3de50606060405260e060020a600035046314ea1cf881146024575b6007565b600060036004803591820183905560058201839055810182905590815560016101f582018190556101f682015560646101f79091015500",
    info: {
      abiDefinition: [{...}],
      compilerOptions: "--combined-json bin,abi,userdoc,devdoc --add-std --optimize",
      compilerVersion: "0.4.4",
      developerDoc: {
        methods: {}
      },
      language: "Solidity",
      languageVersion: "0.4.4",
      source: "library LinkedList { uint80 constant None = uint80(0);  struct data { uint256 head;  Node[100] n;  uint size; uint insert_number; uint buffer_size; } struct Node { string data;  address owner;  uint own;  uint prev; uint next;  } function construct_me(data storage self){  self.n[0].own = 0; self.n[0].next = 0; self.n[0].prev = 0; self.head = 0; self.insert_number = self.size = 1;  self.buffer_size = 100; }}contract owned {  address public owner; function owned() { owner = msg.sender; } function ownerOnly() { if (msg.sender != owner) throw; } modifier onlyOwner { if (msg.sender != owner) throw; _; } function transferOwnership(address newOwner) onlyOwner { owner = newOwner; }}contract Array is owned { using LinkedList for LinkedList.data; using LinkedList for LinkedList.Node; LinkedList.data list; function Array(){  if( test_callstack() != 1 ) throw;  list.construct_me(); } function test_callstack() constant returns ( int ){ return 1; }}",
      userDoc: {
        methods: {}
      }
    }
  },
  owned: {
    code: "0x6060604052600080546c0100000000000000000000000033810204600160a060020a031990911617905560db806100366000396000f3606060405260e060020a6000350463896f40dd811460305780638da5cb5b14604f578063f2fde38b146064575b6002565b34600257608660005433600160a060020a0390811691161460a4576002565b346002576088600054600160a060020a031681565b34600257608660043560005433600160a060020a0390811691161460a6576002565b005b60408051600160a060020a039092168252519081900360200190f35b565b600080546c010000000000000000000000008084020473ffffffffffffffffffffffffffffffffffffffff199091161790555056",
    info: {
      abiDefinition: [{...}, {...}, {...}, {...}],
      compilerOptions: "--combined-json bin,abi,userdoc,devdoc --add-std --optimize",
      compilerVersion: "0.4.4",
      developerDoc: {
        methods: {}
      },
      language: "Solidity",
      languageVersion: "0.4.4",
      source: "library LinkedList { uint80 constant None = uint80(0);  struct data { uint256 head;  Node[100] n;  uint size; uint insert_number; uint buffer_size; } struct Node { string data;  address owner;  uint own;  uint prev; uint next;  } function construct_me(data storage self){  self.n[0].own = 0; self.n[0].next = 0; self.n[0].prev = 0; self.head = 0; self.insert_number = self.size = 1;  self.buffer_size = 100; }}contract owned {  address public owner; function owned() { owner = msg.sender; } function ownerOnly() { if (msg.sender != owner) throw; } modifier onlyOwner { if (msg.sender != owner) throw; _; } function transferOwnership(address newOwner) onlyOwner { owner = newOwner; }}contract Array is owned { using LinkedList for LinkedList.data; using LinkedList for LinkedList.Node; LinkedList.data list; function Array(){  if( test_callstack() != 1 ) throw;  list.construct_me(); } function test_callstack() constant returns ( int ){ return 1; }}",
      userDoc: {
        methods: {}
      }
    }
  }
}

Note that myContractCompiled.Array.code contains the text __LinkedList__...___. This will need to be replaced with the address (without the 0x prefix) of the deployed LinkedList library.

Deploy the LinkedList library:

> var myLinkedListLib = web3.eth.contract(myContractCompiled.LinkedList.info.abiDefinition);
undefined
> var linkedListLib = myLinkedListLib.new({
    from:web3.eth.accounts[0],
    data: myContractCompiled.LinkedList.code, gas: 400000},
    function(e, contract) {
      if (!e) {
        if (!contract.address) {
          console.log("Contract transaction send: TransactionHash: " +
            contract.transactionHash + " waiting to be mined...");
        } else {
          console.log("Contract mined! Address: " + contract.address);
          console.log(contract);
        }
    }
})
Contract transaction send: TransactionHash: 0x420908d8f22649542d532f256dff3ae5a7b473c68c68274d8c83ba9539f6d0e1 waiting to be mined...
Contract mined! Address: 0xc6fa3b899c8840585e706f90d1e43c7229cf9d5d

Let's check the gas used:

> eth.getTransactionReceipt("0x420908d8f22649542d532f256dff3ae5a7b473c68c68274d8c83ba9539f6d0e1")
{
  blockHash: "0xff0ba9946211a9d3b0824e5758d148334ef1de6689c8fba70916e52bd35e2167",
  blockNumber: 2370,
  contractAddress: "0xc6fa3b899c8840585e706f90d1e43c7229cf9d5d",
  cumulativeGasUsed: 78469,
  from: "0x000d1009bd8f0b1301cc5edc28ed1222a3ce671e",
  gasUsed: 78469,
  logs: [],
  logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  root: "0x9c7f63caedfd133826622a2872907fc52ede05cc9c0b644bfadf92bcfa5aaed5",
  to: null,
  transactionHash: "0x420908d8f22649542d532f256dff3ae5a7b473c68c68274d8c83ba9539f6d0e1",
  transactionIndex: 0
}

Replace the __LinkedList__* text with the above address in the Array contract code.

> var arrayCode = myContractCompiled.Array.code.replace(/__LinkedList__+/g, "c6fa3b899c8840585e706f90d1e43c7229cf9d5d")
undefined
> arrayCode
"0x6060604081905260008054600160a060020a0319166c01000000000000000000000000338102041781557f14ea1cf8000000000000000000000000000000000000000000000000000000008252600160645273c6fa3b899c8840585e706f90d1e43c7229cf9d5d916314ea1cf89160849160248186803b1560025760325a03f41560025750505060fd806100936000396000f3606060405260e060020a60003504631309238c8114603a578063896f40dd1460525780638da5cb5b146071578063f2fde38b146086575b6002565b34600257600160408051918252519081900360200190f35b3460025760a860005433600160a060020a0390811691161460c6576002565b3460025760aa600054600160a060020a031681565b3460025760a860043560005433600160a060020a0390811691161460c8576002565b005b60408051600160a060020a039092168252519081900360200190f35b565b600080546c010000000000000000000000008084020473ffffffffffffffffffffffffffffffffffffffff199091161790555056"

Deploy Array with the modified code:

> var myArray = web3.eth.contract(myContractCompiled.Array.info.abiDefinition);
undefined
> var array = myArray.new({
    from:web3.eth.accounts[0],
    data: arrayCode, gas: 400000},
    function(e, contract) {
      if (!e) {
        if (!contract.address) {
          console.log("Contract transaction send: TransactionHash: " +
            contract.transactionHash + " waiting to be mined...");
        } else {
          console.log("Contract mined! Address: " + contract.address);
          console.log(contract);
        }
    }
})
Contract transaction send: TransactionHash: 0x2652d322915ec6f3668a701b5ef41c09cf5aa93de0fd7c18f8de9250a9811505 waiting to be mined...
undefined
...
Contract mined! Address: 0x036a55eb6419b503692eeedd3c446f9252642001

I0103 19:47:37.967249 miner/worker.go:516] commit new work on block 1504 with 1 txs & 0 uncles. Took 4.177908ms
...
> eth.getTransactionReceipt("0x2652d322915ec6f3668a701b5ef41c09cf5aa93de0fd7c18f8de9250a9811505")
{
  blockHash: "0xb6da4bcb8349333f023ed9fc41c47275e27bd1cc446c130842ee8eda51323ee9",
  blockNumber: 2429,
  contractAddress: "0x036a55eb6419b503692eeedd3c446f9252642001",
  cumulativeGasUsed: 227373,
  from: "0x000d1009bd8f0b1301cc5edc28ed1222a3ce671e",
  gasUsed: 227373,
  logs: [],
  logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  root: "0x4fe08613be0eb3475f25cec740b723d8124161bc36093cf2064543ef3e6cdd45",
  to: null,
  transactionHash: "0x2652d322915ec6f3668a701b5ef41c09cf5aa93de0fd7c18f8de9250a9811505",
  transactionIndex: 0
}

Let's test your function:

> array.test_callstack()
1

Note: The code above requires the homesteadBlock configuration to be specified in your genesis.json if you are deploying your library calling contract to a private/dev network - see How to call Library Function from a Contract? => [error] The contract code couldn't be stored, please check your gas amount. undefined.

  • 1
    Increase it to a large value, e.g., 4,000,000 . Then use eth.getTransactionReceipt({txhash}) to find out the exact number of gas required to deploy your code. Then just use a number slightly larger than the required gas. – Bokky WeAreAllAssange PooBah Jan 3 '17 at 2:11
  • 1
    When I deploy same contract through Solidity: Transaction cost is 2046298 gas and it mines. Later I gave slightly higher gas value inside solc as you suggested. Everything works but the transaction never mines and nothing happens after (waiting to be mined...) output inside geth. – alper Jan 3 '17 at 7:25
  • 1
    gist.github.com/avatar-lavventura/… Please note that I am deploying on my private blockchain network. Thank you @BokkyPooBah. – alper Jan 3 '17 at 8:04
  • 1
    I've deployed your code to my --dev blockchain successfully - updated details in my answer. – Bokky WeAreAllAssange PooBah Jan 3 '17 at 14:40
  • 1
    --dev is not required. You just need the homesteadBlock specified in the genesis.json if you are using a private dev network - see ethereum.stackexchange.com/questions/9178/… as this is required to enable the calling of the library functions. – Bokky WeAreAllAssange PooBah Jan 3 '17 at 19:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.