How to add funds to a z-address in regtest mode?

I’m running a Zcash node in regtest mode. To generate some funds, I run the following command :

zcash-cli generate 201

Now when I run zcash-cli getinfo, I see that I have some balance in my wallet.

{
  "version": 2000050,
  "protocolversion": 170007,
  "walletversion": 60000,
  "balance": 1946.25000000,
  "blocks": 322,
  "timeoffset": 0,
  "connections": 0,
  "proxy": "",
  "difficulty": 1.000018239355057,
  "testnet": false,
  "keypoololdest": 1538977421,
  "keypoolsize": 101,
  "paytxfee": 0.00000000,
  "relayfee": 0.00000100,
  "errors": "WARNING: check your network connection, 5 blocks received in the last 4 hours (96 expected)"
}

I created to z-addresses, let’s assume them as z1 and z2 respectively.
Now when I’m trying to transfer funds from z1 to z2, I get an error stating insufficient funds. So how shall I add fund to a z-address?
Also can anyone explain me the basic idea how addresses within a wallet works, not talking about t-address.

When Sapling activates if you have funds sitting in a private Sprout address they must first be sent to a transparent address before they can be sent to a private Sapling address.

Check the outputs of z_listunspent for z-addrs and listunspent for t-addrs to find which addresses have funds in.

Then simply use z_sendmany to send funds as per the documentation Zcash Payment API — Zcash Documentation 5.2.0 documentation

The only exception is when using coinbase inputs where special consensus rules apply (funds must be shielded before they can be spent and no change allowed) but there is a special command to help out there z_shieldcoinbase e.g zcash-cli help z_shieldcoinbase.

Thanks for the information, What do we mean by coinbase?

Also I did tried to transfer from t-address to a z-address, however I get the following error :

 {
    "id": "opid-f8b90b14-13e4-4f1f-a19d-4e7cfe7e022e",
    "status": "failed",
    "creation_time": 1539238774,
    "error": {
      "code": -4,
      "message": "Change 4.9999 not allowed. When protecting coinbase funds, the wallet does not allow any change as there is currently no way to specify a change address in z_sendmany."
    },
    "method": "z_sendmany",
    "params": {
      "fromaddress": "tmLrJZvHzq4tiCvKVPTn2XNocv2RLjuoxkj",
      "amounts": [
        {
          "amount": 5.0,
          "address": "ztPbqXkLKsfDsVRgoeigaGK3F8y9ghyvahUYjorWGQph6TfpW5dV99AEA6MpZG4HdQXJpyx7rMPTUM8G93DwZo8sLioxpoz"
        }
      ],
      "minconf": 1,
      "fee": 0.0001
    }
  }

I also run the following command for the coinbase thing :

zcash-cli z_shieldcoinbase "tmLrJZvHzq4tiCvKVPTn2XNocv2RLjuoxkj" "ztPbqXkLKsfDsVRgoeigaGK3F8y9ghyvahUYjorWGQph6TfpW5dV99AEA6MpZG4HdQXJpyx7rMPTUM8G93DwZo8sLioxpoz"

And then tried to transfer, but same error.

Also how do I add funds to a z-address initially, so I do no need to repeat this.

The coinbase output is what pays the miner reward. As you are on regtest mode and mined those blocks your funds are in coinbase outputs. As I said before these funds have special rules - they have to be shielded before they can be spent and no change allowed.

So that original error is very informative as, you can’t have change when shielding coinbase funds so either just send the full amount or use the z_shieldcoinbase command and it’ll handle things for you.

Try this. z_shieldcoinbase "*" "your-z-addr" as this will send all of your mining rewards (the default limit is 50) though it should have worked as you wrote it above assuming the coinbase funds are in that t-addr but this way is simpler. See this for more details z_shieldcoinbase - Zcash 4.5.1-1 RPC Docs