Learning to use the demo endpoint

David Lypka, [28.10.19 20:15]
I am still not clear how to play with the endpoint you have already provided. I got the go to build fine on my ubuntu and I ran the url to get the list JSON snippet with the key, but I still do not know what to do next exactly. I am guessing I have to take the sample .env and just copy it somewhere and maybe edit it to put that key into it. But then what? is the Daemon invoked automatically so no need to explicitly start up the daemon? just run the client? Then make some kind of Action request I suppose. I forget if it says somewhere which Actions are supported in the sample demo endpoint? OK I will not think like the (dumb) Ethereum cross checking approach…

Curtis Ellis, [28.10.19 20:17]
yeah, copy the .env and put your values in, then execute it so it sets your environment variables. this means passing it to the “source” command on linux.

Calling that endpoint gives you access to a smart contract agent where the daemon is already running. so you don’t have to do anything with a daemon. you just run the client and send requests to the daemon through on change transactions to the contract address.

David Lypka, [28.10.19 20:19]
What is the endpoint address precisely? Is it the same one that gave me the key?
Oh, I see just call it with a different action now, right?
Just one endpoint provides all the services I need then?

David Lypka, [28.10.19 20:19]
Use the source command to consume the .env, OK.

David Lypka, [28.10.19 20:19]
Daemon is already running at that endpoint, OK

Any more questions on this, David?

Yes I still need more specifics for how to run a little sample contract on the demo endpoint.
All I was told was
"After you have the address, you will need to compose a contract offer message to initialize it and an asset definition message to create an asset (token)."
That is a pretty general set of instructions for a beginner to act on.
So please advise a specific “hello world” kind of “contract offer message” to “compose” and the related “asset definition message to create an asset”.
And how exactly to run it in the CLI

Thanks.

This helps understand what the initial messages are to create a contract.
https://tokenized.com/docs/concepts/contracts

Then this can explain creating assets.
https://tokenized.com/docs/concepts/asset-management

After you have those ideas down you can use the CLI to execute them.

  1. Setup your CLI config file with your admin key and contract address, and run it to update your environment. (you can create an admin key with CLI gen)
  2. Send some bitcoin to the address admin key’s address.
  3. Run CLI sync to update it so it sees the bitcoin.
  4. Create Contract offer json. A json file containing fields from contract offer message.
  5. Run CLI build to encode the json as a tokenized message. Test with just --tx parameter, then when you think it is right you can broadcast with --tx --send.
  6. Check an online explorer for your contract address to see if it responded with a C2 message.
  7. Run CLI sync again to sync the new transaction.
  8. Do the same for the asset definition message.

OK after weeks of private reflection on these instructions, I have made it this far today but now I am stuck. I keep detailed notes on the steps I take, so here are the relevant notes leading up to where I am stuck:
dlypka@dlypka-VirtualBox:~/go/bin$ ./smartcontract gen -h

Generates a bitcoin private key in WIF

Usage:

smartcontract gen [flags]

Flags:

-h, --help help for gen

dlypka@dlypka-VirtualBox:~/go/bin$ ./smartcontract gen

WARNING!! No Bitcoin network specified. Set environment value BITCOIN_CHAIN=testnet

dlypka@dlypka-VirtualBox:~/go/bin$ # So using the bin did not work…

dlypka@dlypka-VirtualBox:~/go/src/github.com/tokenized/smart-contract/conf$ ls -la
total 24
drwxrwxr-x 2 dlypka dlypka 4096 Oct 22 23:32 .
drwxrwxr-x 10 dlypka dlypka 4096 Oct 23 00:49 …
-rw-rw-r-- 1 dlypka dlypka 633 Oct 22 23:32 cli_dev.env.bat.example
-rw-rw-r-- 1 dlypka dlypka 683 Oct 22 23:32 cli.dev.env.example
-rw-rw-r-- 1 dlypka dlypka 1028 Oct 22 23:32 dev.env.bat.example
-rw-rw-r-- 1 dlypka dlypka 1056 Oct 22 23:32 dev.env.example
dlypka@dlypka-VirtualBox:~/go/src/github.com/tokenized/smart-contract/conf$

From my gmail https://mail.google.com/mail/u/0/?shva=1#label/Blockchain+Tokenized/FMfcgxwDrlfrFmrxSwTtJJVMdgKLpxfm

A Tokenized smart contract works by having an identifying address.

The address is the same as any standard bitcoin address

The only difference is that a smart contract agent is monitoring transactions that contain outputs to that address for Tokenized request messages.

To get a contract address, open this [link].

http:///new_contract

{“address”:“1JfU62HvMaSPsUVWbtfwPkQT66EZcrpBUB”,“contract_fee”:2000}

It should give you some text containing a bitcoin address.

Be aware that the address will expire after 4 hours or so if you have not sent a valid contract offer message to it yet. If it expires, you can open the link again for a new address. This address will only be for testing purposes and we can’t guarantee anything because we are still making changes to the protocol and your contract may become invalid. But it should allow you to start developing software to interact with the Tokenized protocol.

After you have the address, you will need to compose a contract offer message to initialize it and an asset definition message to create an asset (token).You can do this with your own software

or for testing purposes with the CLI (command line interface ./smartcontract) provided with the smart-contract software repository. https://github.com/tokenized/smart-contract

Curtis Ellis, [23.10.19 01:52]

but I usually run CLI with "go run cmd/smartcontract/main.go "

WHY the vague term CLI is used here is beyond me…
There is no code with the name CLI anywhere that I can see, so why say CLI to newbies?

From Learning to use the demo endpoint Curtis Ellis

This helps understand what the initial messages are to create a contract.

https://tokenized.com/docs/concepts/contracts

Then this can explain creating assets.

https://tokenized.com/docs/concepts/asset-management

After you have those ideas down you can use the CLI to execute them.

  1. Setup your CLI config file with your admin key and contract address, and run it to update your environment. (you can create an admin key with CLI gen which is actually ./smartcontract gen)
  2. Send some bitcoin BSV to the address admin key’s address.
  3. Run CLI sync to update it so it sees the bitcoin.
  4. Create Contract offer json. A json file containing fields from contract offer message.
  5. Run CLI build to encode the json as a tokenized message. Test with just --tx parameter, then when you think it is right you can broadcast with --tx --send.
  6. Check an online explorer for your contract address to see if it responded with a C2 message.
  7. Run CLI sync again to sync the new transaction.
  8. Do the same for the asset definition message.

Here is the sample env
~/go/src/github.com/tokenized/smart-contract/conf/cli.dev.env

!/bin/bash

Config for a standalone contract instance.

the local node to connect to.

export CLIENT_NODE_ADDRESS=127.0.0.1:8333

export CLIENT_NODE_USER_AGENT="/TokenizedClient:0.1.0/"

Block 560,000

export CLIENT_START_HASH=“0000000000000000035cb1baaf4f82d8358a8b9ed22aec52c2801a02b9c6f18f”

Your key in WIF format (this is an example)

export CLIENT_WALLET_KEY=92Vm8eFmeEeGqdSPwA2KMwZEJ45zW1Wi5esK1Ptg6MSDckRikvZ

Address of contract in standard bitcoin format

export CLIENT_CONTRACT_ADDRESS=n1R4ViAM21hoKs3qw1m7p7MUKjXgmU8NQm

Where to store state files

export CLIENT_PATH=./client

export CLIENT_LOG_FILE_PATH=./main.log

export BITCOIN_CHAIN=testnet

Here is a total guess on my part, which luckily works:
Here is the magic step
dlypka@dlypka-VirtualBox:~/go/src/github.com/tokenized/smart-contract$
go run ./cmd/smartcontract/main.go gen

WIF : 91ds7StSgD9hXjePTgoZDpMRCgRE5jS3e36LUD6CjghPsgyGY9c

PubKey : AuUkwdL778FZNIq9IT+4h14JuHNkUNKYTJ74PCdSiT+U

Addr : n13485tnABkj5XgMooXuE1dPtj9BPRPXSq

Now read the help about what the smartcontract (AKA “CLI”) command does:

dlypka@dlypka-VirtualBox:~/go/bin$ ./smartcontract gen -h

Generates a bitcoin private key in WIF

Usage:

smartcontract gen [flags]

So we need to copy the WIF private key into

~/go/src/github.com/tokenized/smart-contract/conf/cli.dev.env

to replace

export CLIENT_WALLET_KEY=92Vm8eFmeEeGqdSPwA2KMwZEJ45zW1Wi5esK1Ptg6MSDckRikvZ

with

export CLIENT_WALLET_KEY=91ds7StSgD9hXjePTgoZDpMRCgRE5jS3e36LUD6CjghPsgyGY9c

And

To get a contract address, open this link

http:///new_contract

{“address”:“1JfU62HvMaSPsUVWbtfwPkQT66EZcrpBUB”,“contract_fee”:2000}

So we have to replace

export CLIENT_CONTRACT_ADDRESS=n1R4ViAM21hoKs3qw1m7p7MUKjXgmU8NQm

with

export CLIENT_CONTRACT_ADDRESS=1JfU62HvMaSPsUVWbtfwPkQT66EZcrpBUB

Updated env file:
#!/bin/bash

~/go/src/github.com/tokenized/smart-contract/conf/cli.dev.env

Config for a standalone contract instance.

the local node to connect to.

export CLIENT_NODE_ADDRESS=127.0.0.1:8333

export CLIENT_NODE_USER_AGENT="/TokenizedClient:0.1.0/"

Block 560,000

export CLIENT_START_HASH=“0000000000000000035cb1baaf4f82d8358a8b9ed22aec52c2801a02b9c6f18f”

Your key in WIF format (this is an example)

#export CLIENT_WALLET_KEY=92Vm8eFmeEeGqdSPwA2KMwZEJ45zW1Wi5esK1Ptg6MSDckRikvZ

export CLIENT_WALLET_KEY=91ds7StSgD9hXjePTgoZDpMRCgRE5jS3e36LUD6CjghPsgyGY9c

Address of contract in standard bitcoin format

#export CLIENT_CONTRACT_ADDRESS=n1R4ViAM21hoKs3qw1m7p7MUKjXgmU8NQm

export CLIENT_CONTRACT_ADDRESS=1JfU62HvMaSPsUVWbtfwPkQT66EZcrpBUB

Where to store state files

export CLIENT_PATH=./client

export CLIENT_LOG_FILE_PATH=./main.log

export BITCOIN_CHAIN=testnet

NOW I AM STUCK HERE:

So now I have completed the 2 parameter updates but then it says to run it to 'update"

  1. Setup your CLI config file with your admin key and contract address, and run it to update your environment. (you can create an admin key with CLI gen which is actually ./smartcontract gen)

How to “run it to update your environment”???

So using the bin did not work…

Our build process doesn’t currently place executable files in ~/go/bin. It places them in the dist directory of the repo. So that executable is probably just old. Please use either go run or the executable in dist. I believe if you run go get again it will update the executable in ~/go/bin.

WHY the vague term CLI is used here is beyond me…
There is no code with the name CLI anywhere that I can see, so why say CLI to newbies?

Sorry for the confusion. CLI is an acronym for “Command Line Interface”, which is what cmd/smartcontract is. I thought it was common knowledge. This software is currently really only designed as a tool for software developers, so a certain amount of domain knowledge is going to be required.

How to “run it to update your environment”???

By “run it”, I meant to run the config file so it updates your environment variables. On Linux that means running source conf/<config file name>

OHH you mean use the source command.
OK will do.
I know that CLI is Command Line Interface, but as a newbie that does not easily clue me into what
I need to run, which is ./smartcontract

Buried in my info is the important step I found to get it to start working:

#Here is the magic step
dlypka@dlypka-VirtualBox:~/go/src/github.com/tokenized/smart-contract$
go run ./cmd/smartcontract/main.go gen

WIF : 91ds7StSgD9hXjePTgoZDpMRCgRE5jS3e36LUD6CjghPsgyGY9c

PubKey : AuUkwdL778FZNIq9IT+4h14JuHNkUNKYTJ74PCdSiT+U

Addr : n13485tnABkj5XgMooXuE1dPtj9BPRPXS

So instead of messing with the binaries, I intend to continue using
cd ~/go/src/github.com/tokenized/smart-contract
go run ./cmd/smartcontract/main.go

I imagine that the ‘gen’ option does not look at cli.dev.env, right?
But do most of the other options use it?

Yeah, any commands that need the config values will use those specified in that config.

OK now I have to do Steps 2 thru 8.

QUESTION: For Exactly which prior steps should Step 8 "Do the same"

  1. Send some bitcoin BSV to the address admin key’s address n13485tnABkj5XgMooXuE1dPtj9BPRPXSq
    Maybe use MoneyButton or SimpleSwap or other BSV Wallet. I used SQUARE Cash App to Buy BTC then Exchanged to BSV on SimpleSwap.io

  2. Run CLI sync to update it so it sees the bitcoin.

  3. Create Contract offer json. A json file containing fields from contract offer message.

  4. Run CLI build to encode the json as a tokenized message. Test with just --tx parameter, then when you think it is right you can broadcast with --tx --send.

  5. Check an online explorer for your contract address to see if it responded with a C2 message.

  6. Run CLI sync again to sync the new transaction.

  7. Do the same for the asset definition message

4 through 7 where you created the “Contract Offer”. Just do the same except with an “Asset Definition”.

OK thanks.
And I will run the gen again to get new keys since I published these publicly here.

OK there is a new problem because I am running into confused multiple BSV addresses for the contract.
The confusion is caused by #1 getting BSV Address here:
http:///new_contract

But then later, #2 it gives a 2nd BSV address from here:
go run ./cmd/smartcontract/main.go gen

WIF : 92TNoPL1inUADuPFqUSqSZmKHtmWKPVsLwj2Hmgu3z97ZghYice

PubKey : A8c2B2raM4+hJ402OGhvza+0MJcV+5mgw+jB9/TH3FAz

Addr : mxcrFykGCz4iGbG2dVctKUXNxDLzRiZt5g <=== 2nd BSV Address

So I lost my 10 cents of BSV I sent from Moneybutton because it crashed on
go run ./cmd/smartcontract/main.go sync

I believe that the error was complaining about the BSV addresss having 0 funds and it was displaying the old BSV address I had a week ago instead of latest address I had generated.

dlypka@dlypka-VirtualBox:~/go/src/github.com/tokenized/smart-contract$ go run ./cmd/smartcontract/main.go sync
2019/11/30 02:11:54.085739 [Main] wallet.go:161 Info - Loaded wallet with 0 outputs, 0 unspent, and balance of 0.00000000
2019/11/30 02:11:54.086429 [Main] wallet.go:164 Info - Wallet address : n13485tnABkj5XgMooXuE1dPtj9BPRPXSq
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x58 pc=0x9fa83b]

goroutine 1 [running]:
[github.com/tokenized/smart-contract/cmd/smartcontract/client.(*Client).setupSpyNode(0x0](http://github.com/tokenized/smart-contract/cmd/smartcontract/client.(*Client).setupSpyNode(0x0), 0xfb11e0, 0xc000372540, 0x20, 0xc000090380)
/home/dlypka/go/src/github.com/tokenized/smart-contract/cmd/smartcontract/client/node.go:121 +0x15b
[github.com/tokenized/smart-contract/cmd/smartcontract/client.(*Client).RunSpyNode(0x0](http://github.com/tokenized/smart-contract/cmd/smartcontract/client.(*Client).RunSpyNode(0x0), 0xfb11e0, 0xc000372540, 0x1, 0x0, 0x0)
/home/dlypka/go/src/github.com/tokenized/smart-contract/cmd/smartcontract/client/node.go:137 +0x68
[github.com/tokenized/smart-contract/cmd/smartcontract/cmd.glob..func13(0x149dda0](http://github.com/tokenized/smart-contract/cmd/smartcontract/cmd.glob..func13(0x149dda0), 0x14c1df0, 0x0, 0x0, 0x0, 0x0)
/home/dlypka/go/src/github.com/tokenized/smart-contract/cmd/smartcontract/cmd/cmd_sync.go:29 +0x10e
[github.com/spf13/cobra.(*Command).execute(0x149dda0](http://github.com/spf13/cobra.(*Command).execute(0x149dda0), 0x14c1df0, 0x0, 0x0, 0x149dda0, 0x14c1df0)
/home/dlypka/go/src/github.com/spf13/cobra/command.go:829 +0x460
[github.com/spf13/cobra.(*Command).ExecuteC(0x149e020](http://github.com/spf13/cobra.(*Command).ExecuteC(0x149e020), 0xc000359f38, 0x1, 0x1)
/home/dlypka/go/src/github.com/spf13/cobra/command.go:917 +0x2fb
github.com/spf13/cobra.(*Command).Execute(…
/home/dlypka/go/src/github.com/spf13/cobra/command.go:867
github.com/tokenized/smart-contract/cmd/smartcontract/cmd.Execute()
/home/dlypka/go/src/github.com/tokenized/smart-contract/cmd/smartcontract/cmd/main.go:36 +0x37e
main.main()
/home/dlypka/go/src/github.com/tokenized/smart-contract/cmd/smartcontract/main.go:8 +0x20
exit status 2

Here is how I set it up:

file cli.dev.env (NOTE for the forum I replaced the hash by - because hash messes the formatting)

  • the local node to connect to.
    export CLIENT_NODE_ADDRESS=127.0.0.1:8333
    export CLIENT_NODE_USER_AGENT="/TokenizedClient:0.1.0/"

  • Block 560,000
    export CLIENT_START_HASH=“0000000000000000035cb1baaf4f82d8358a8b9ed22aec52c2801a02b9c6f18f”

  • Your key in WIF format (this is an example)
    -export CLIENT_WALLET_KEY=92Vm8eFmeEeGqdSPwA2KMwZEJ45zW1Wi5esK1Ptg6MSDckRikvZ
    export CLIENT_WALLET_KEY=92TNoPL1inUADuPFqUSqSZmKHtmWKPVsLwj2Hmgu3z97ZghYice

  • Address of contract in standard bitcoin format
    -export CLIENT_CONTRACT_ADDRESS=n1R4ViAM21hoKs3qw1m7p7MUKjXgmU8NQm
    export CLIENT_CONTRACT_ADDRESS= 1Czxji5bCNc8T3baANcRBXgc4uCJWCmRrZ

  • Where to store state files
    export CLIENT_PATH=./client

export CLIENT_LOG_FILE_PATH=./main.log

export BITCOIN_CHAIN=testnet


dlypka@dlypka-VirtualBox:~/go/src/[github.com/tokenized/smart-contract$ source ./conf/cli.dev.env

dlypka@dlypka-VirtualBox:~/go/src/[github.com/tokenized/smart-contract$ go run ./cmd/smartcontract/main.go gen
WIF : 91qjEfnrR5S38PqjUVDyhdeE1KuAdrNfHXX57LRGVKY332fx9FT
PubKey : A0I/rb74WqxndZKjdE5GFBpWGBRgGlZCW4Tk3C0tfCNW
Addr : miBdpqNbxuAVV3WAXUZ63g4JUYrdSPZEiJ

dlypka@dlypka-VirtualBox:~/go/src/[github.com/tokenized/smart-contract$ echo $CLIENT_CONTRACT_ADDRESS
1Czxji5bCNc8T3baANcRBXgc4uCJWCmRrZ

dlypka@dlypka-VirtualBox:~/go/src/[github.com/tokenized/smart-contract$

This is NOT what I EXPECT.

I EXPECT TO SEE Addr : 1Czxji5bCNc8T3baANcRBXgc4uCJWCmRrZ

But is has output Addr : miBdpqNbxuAVV3WAXUZ63g4JUYrdSPZEiJ

So please explain more details about which of the 2 BSV address does what and when to use in what steps more precisely.

#1 is the contract address (CLIENT_CONTRACT_ADDRESS). It is the address that the smart contract agent is monitoring and operating on. Requests are sent to that address and the smart contract agent responds to those requests and signs them with the key associated with that address. When you hit that endpoint, which is not public knowledge as it is just for testing, it creates a new address and activates a smart contract agent on that address.

#2 is to create a key/address (single key wallet) to use as administrator for testing (CLIENT_WALLET_KEY). In production you will use a normal wallet and a fully functional application. This address needs to be funded by you with a small amount of bitcoin (like $0.10), then it is used to create and fund requests to the smart contract.

The sync command cannot lose your funds. They are still there if you sent them to an address you have the private key for. After you generate the address you have to put it in your config file and “apply” your config file so it updates your environment variables that are used by the sync command. If you change the address you need to clear the files generated by spynode so it will sync from the start block for the new address.

Keep in mind that these command line features are a very rough testing system and you probably need to have a good understanding of bitcoin and smart contracts to use them properly.

The error you are getting looks like it is from not updating your environment variables with the config file before running the command.

Running gen does not update your config or apply it to your environment variables. It simple generates a new key and displays the WIF of the private key, as well as the public key and address associated.

But I always update first - using the “source” command.

It shows the source command in the console output I included there in the forum post

Your reply does not seem to be answering my question and you are mixing up key and address.

I am asking WHY does it look like we have 2 BSV Addresses??? (1 from endpoint JSON and 1 from gen command). Plus we also have a Private Key in WIF format created by the gen command.

The config file only has a property for 1 BSV Address it seems. So where do the 2 BSV Addresses go in what config properties exactly or where else are they consumed?

OR are you implying that CLIENT_WALLET_KEY is misnamed and is actually to be thought of as CLIENT_WALLET_ADDRESS?

So then the WIF is not needed in the config at all and is just provided for funds recovery as in my case of the 10 cents?

I had been putting the WIF value into CLIENT_WALLET_KEY since the property name reads as a “_KEY”.

Also when you explained that I “need to clear the files generated by spynode”, is that an extra step beyond calling the sync command? Is it something that we have not discussed so far? I do not recall
reading or hearing about “spynode”.

Where you got the error “panic: runtime error: invalid memory address or nil pointer dereference”, there was no source command before it. That is where I was saying the issue was likely related to not having called source.

Sorry if key and address are unclear. An address is just a hash of the public key associated with a private key. The gen command generates a private key and displays all three of those values associated with that private key. You only need one key for your wallet to be used to administer the smart contract. You will only know the address of the smart contract agent, not the private key.

So you will have 2 addresses, one for the smart contract, and one for the single key administration wallet. You will only have one private key, the one for your administration wallet.

You put the private key of your administration wallet into the config so it has the ability to sign requests for you.

You then also put the address of the smart contract agent in the config so it can send the request to that address so the agent sees it.

WIF stands for Wallet Import Format and is just a method of encoding a private key as text. It actually represents a 256 bit private key.

Clearing spynode is only needed if you are changing your administration key/address. Ideally you should not need to do that or run different wallets from different directories. Spynode is the subsystem that is responsible for communicating with the bitcoin network and synchronizing UTXOs and state. If you are using the default file structure, to clear the spynode data you will need to delete the directory “./tmp/client/standalone/spynode”.

OH OK that is different than what I guessed.

So the Wallet Address which is output from the gen command is not used in the config at all!

The Wallet Address is only to be used as the destination for sending BSV funds to the wallet.

To Summarize: the config has

1. address of the smart contract agent which comes from the Endpoint URL query and is ONLY GOOD FOR 4 HOURS

2. private key in WIF Format of  your administration wallet 
    and this is output from the gen command. It is for signing requests.

OK I will try it that way and see what happens.

Thanks for the clarification.

Yes, technically the wallet address is used internally in bitcoin transactions, but it is derived from the private key specified in the config.

I found 2 folders with spynode data.

Question: Should I delete BOTH spynode folders?

dlypka@dlypka-VirtualBox:~/go/src/github.com/tokenized/smart-contract/pkg/spynode/handlers/storage/tmp/test/standalone/spynode$ ls -la
total 24
drwxr-xr-x 5 dlypka dlypka 4096 Oct 23 00:50 .
drwxr-xr-x 3 dlypka dlypka 4096 Oct 23 00:50 …
drwxr-xr-x 2 dlypka dlypka 4096 Oct 23 00:50 blocks
-rw-rw-r-- 1 dlypka dlypka 116 Oct 23 00:50 peers
drwxr-xr-x 2 dlypka dlypka 4096 Oct 23 00:50 reorgs
drwxr-xr-x 2 dlypka dlypka 4096 Oct 23 00:50 txs

dlypka@dlypka-VirtualBox:~/go/src/github.com/tokenized/smart-contract/pkg/spynode/handlers/tmp/test/standalone/spynode$ ls -la
total 16
drwxr-xr-x 4 dlypka dlypka 4096 Oct 23 00:50 .
drwxr-xr-x 3 dlypka dlypka 4096 Oct 23 00:50 …
drwxr-xr-x 2 dlypka dlypka 4096 Oct 23 00:50 blocks
drwxr-xr-x 2 dlypka dlypka 4096 Oct 23 00:50 reorg

Those are both just data from running tests. They have “tmp/test” in the path. Unless you changed the path in the config file or configured S3 storage it should be “~/go/src/github.com/tokenized/smart-contract/tmp/client/standalone/spynode”.

Sill no luck, same error.

Which items go stale after 4 hours?
Only the contract address?
Or does the Wallet address also go stale?
Does the spynode folder have to be deleted after 4 hours?
Here is where I have spynode:

dlypka@dlypka-VirtualBox:~/go/pkg/linux_amd64/github.com/tokenized/smart-contract/pkg/spynode$

dlypka@dlypka-VirtualBox:~/go/src/github.com/tokenized/smart-contract/pkg/spynode/handlers/tmp/test/standalone/spynode$

dlypka@dlypka-VirtualBox:~/go/src/github.com/tokenized/smart-contract/pkg/spynode/handlers/storage/tmp/test/standalone/spynode$

Here are my file paths in my .env:
Where to store state files
export CLIENT_PATH=./client
export CLIENT_LOG_FILE_PATH=./main.log
export BITCOIN_CHAIN=testnet

I used MoneyButton to send 10 cents to n13485tnABkj5XgMooXuE1dPtj9BPRPXSq

HERE is the Run with the usual error:

dlypka@dlypka-VirtualBox:~/go/src/github.com/tokenized/smart-contract$ source ./conf/cli.dev.env
dlypka@dlypka-VirtualBox:~/go/src/github.com/tokenized/smart-contract$ go run ./cmd/smartcontract/main.go sync
2019/12/08 14:38:45.885937 [Main] wallet.go:161 Info - Loaded wallet with 0 outputs, 0 unspent, and balance of 0.00000000
2019/12/08 14:38:45.910203 [Main] wallet.go:164 Info - Wallet address : n13485tnABkj5XgMooXuE1dPtj9BPRPXSq
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x58 pc=0x9fa83b]

goroutine 1 [running]:
github.com/tokenized/smart-contract/cmd/smartcontract/client.(*Client).setupSpyNode(0x0, 0xfb11e0, 0xc000370540, 0x20, 0xc000090280)
/home/dlypka/go/src/github.com/tokenized/smart-contract/cmd/smartcontract/client/node.go:121 +0x15b
github.com/tokenized/smart-contract/cmd/smartcontract/client.(*Client).RunSpyNode(0x0, 0xfb11e0, 0xc000370540, 0x1, 0x0, 0x0)
/home/dlypka/go/src/github.com/tokenized/smart-contract/cmd/smartcontract/client/node.go:137 +0x68
github.com/tokenized/smart-contract/cmd/smartcontract/cmd.glob..func13(0x149dda0, 0x14c1df0, 0x0, 0x0, 0x0, 0x0)
/home/dlypka/go/src/github.com/tokenized/smart-contract/cmd/smartcontract/cmd/cmd_sync.go:29 +0x10e
github.com/spf13/cobra.(*Command).execute(0x149dda0, 0x14c1df0, 0x0, 0x0, 0x149dda0, 0x14c1df0)
/home/dlypka/go/src/github.com/spf13/cobra/command.go:829 +0x460
github.com/spf13/cobra.(*Command).ExecuteC(0x149e020, 0xc000359f38, 0x1, 0x1)
/home/dlypka/go/src/github.com/spf13/cobra/command.go:917 +0x2fb
github.com/spf13/cobra.(*Command).Execute(…)
/home/dlypka/go/src/github.com/spf13/cobra/command.go:867
github.com/tokenized/smart-contract/cmd/smartcontract/cmd.Execute()
/home/dlypka/go/src/github.com/tokenized/smart-contract/cmd/smartcontract/cmd/main.go:36 +0x37e
main.main()
/home/dlypka/go/src/github.com/tokenized/smart-contract/cmd/smartcontract/main.go:8 +0x20
exit status 2
dlypka@dlypka-VirtualBox:~/go/src/github.com/tokenized/smart-contract$