7

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.

alper
  • 8,395
  • 11
  • 63
  • 152
  • 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 01 '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: http://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 02 '17 at 02:43
  • 1
    By using solc compiler can I deploy contracts to my private blockchain network? @TjadenHess – alper Jan 02 '17 at 12:22
  • you can use mist wallet as well to deploy your contracts. – Himanshu Pandey Jan 02 '17 at 19:58
  • @HimanshuPandey It doesn't solve the problem, it's another GUI basically. – Teleporting Goat Jan 03 '17 at 14:58

1 Answers1

5

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.

BokkyPooBah
  • 40,274
  • 14
  • 123
  • 193
  • OP is asking for solution inside browser-solidity without the GUI. Chicken or Egg? :D – niksmac Dec 31 '16 at 14:48
  • Should I increase the gas value which is 400000 ? because my contract's gas required is much larger. – alper Jan 03 '17 at 02:01
  • 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. – BokkyPooBah Jan 03 '17 at 02:11
  • Post your code or a link to it and I can check it for you, or suggest a few other alternatives. – BokkyPooBah Jan 03 '17 at 06:44
  • 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 03 '17 at 07:25
  • 1
    https://gist.github.com/avatar-lavventura/3496d374fa0b729d9ca78c93729714ce Please note that I am deploying on my private blockchain network. Thank you @BokkyPooBah. – alper Jan 03 '17 at 08:04
  • 1
    I've deployed your code to my --dev blockchain successfully - updated details in my answer. – BokkyPooBah Jan 03 '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 http://ethereum.stackexchange.com/questions/9178/how-to-call-library-function-from-a-contract-error-the-contract-code-could as this is required to enable the calling of the library functions. – BokkyPooBah Jan 03 '17 at 19:16
  • Your solution works perfectly fine. What if I have import "./LinkedList.sol";import "./ReceiptLib.sol"; on my contract what should I do? @BokkyPooBah – alper Apr 08 '17 at 16:34
  • var myContractCompiled=web3.eth.compile.solidity(myContractSource) gives following error: Error: The method eth_compileSolidity does not exist/is not available. I think this function is not in use (https://github.com/ethereum/go-ethereum/issues/3793) and this answer needs to be updated for the latest geth version. @The Officious BokkyPooBah – alper Apr 16 '18 at 08:34