will it work in 2023?
Of course. In testnet, mainnet, signet, and regtest. It works in all official networks, supported by Bitcoin Core.
1. How would I send to the public key (NOT the public address) - in practice?
I will show you that on testnet coins, you can use the same method in all other networks.
First, we can get some testnet address, to get some coins from some faucet.
getnewaddress
tb1qy0vla3d5d2dnex5lpk9ssrjsurr28k42tm68rr
Then, we generate some new address to send to, exactly in the same way:
getnewaddress
tb1qyqlpe9huxzpn9x42ztjdat7u6cslljzkpukqtp
Now, we can ask Bitcoin Core for the public key for our address, as well as many more useful information:
getaddressinfo tb1qyqlpe9huxzpn9x42ztjdat7u6cslljzkpukqtp
{
"address": "tb1qyqlpe9huxzpn9x42ztjdat7u6cslljzkpukqtp",
"scriptPubKey": "0014203e1c96fc3083329aaa12e4deafdcd621ffc856",
"ismine": true,
"solvable": true,
"desc": "wpkh([e4a5a30b/0'/0'/1']023216db7a4dfc8b0926c608162a81828e06622000a4d2c34e87ac1de8c9cc293e)#6sfazyvz",
"iswatchonly": false,
"isscript": false,
"iswitness": true,
"witness_version": 0,
"witness_program": "203e1c96fc3083329aaa12e4deafdcd621ffc856",
"pubkey": "023216db7a4dfc8b0926c608162a81828e06622000a4d2c34e87ac1de8c9cc293e",
"ischange": false,
"timestamp": 1693838034,
"hdkeypath": "m/0'/0'/1'",
"hdseedid": "9c39324ff585908865a69b8f916cbfdf7afb3477",
"hdmasterfingerprint": "e4a5a30b",
"labels": [
""
]
}
Then, we can copy the most interesting part: our public key. It is compressed by default, because we can get Segwit addresses by default, but it can be uncompressed as well, if we force Bitcoin Core to use that. However, in general, we should use compressed ones, because they are cheaper, and they are always standard, when wrapped into Segwit or Taproot.
"pubkey": "023216db7a4dfc8b0926c608162a81828e06622000a4d2c34e87ac1de8c9cc293e"
Now, we are ready to make some transaction, that will send coins to some regular address. Let's just send everything we have into our Segwit address first, just to get transaction data:
createrawtransaction "[{\"txid\":\"a8a552f75b4aad4a1eee859ed9babf0d3347ef49593c1d551c74ebd989795938\",\"vout\":1}]" "[{\"tb1qyqlpe9huxzpn9x42ztjdat7u6cslljzkpukqtp\":0.00012581}]" 0 true
020000000138597989d9eb741c551d3c5949ef47330dbfbad99e85ee1e4aad4a5bf752a5a80100000000fdffffff012531000000000000160014203e1c96fc3083329aaa12e4deafdcd621ffc85600000000
I already put the proper amount, but you can go through the whole procedure first, then get transaction size in virtual bytes, and correct the amount in the end. But I already did that, so I know my transaction would take 123 virtual bytes with all signatures, so I can do it now, to not repeat commands.
Now, we can edit our transaction in Notepad, and replace our Segwit address with P2PK:
020000000138597989d9eb741c551d3c5949ef47330dbfbad99e85ee1e4aad4a5bf752a5a80100000000fdffffff012531000000000000
160014203e1c96fc3083329aaa12e4deafdcd621ffc856 //this part should be replaced
00000000
023216db7a4dfc8b0926c608162a81828e06622000a4d2c34e87ac1de8c9cc293e //this is our public key
2321023216db7a4dfc8b0926c608162a81828e06622000a4d2c34e87ac1de8c9cc293eac //this is our script
020000000138597989d9eb741c551d3c5949ef47330dbfbad99e85ee1e4aad4a5bf752a5a80100000000fdffffff012531000000000000
2321023216db7a4dfc8b0926c608162a81828e06622000a4d2c34e87ac1de8c9cc293eac //this is how we modify our transaction
00000000
And then, we can confirm all of that, if we are not sure. First, to use different Scripts, we can use this command:
decodescript 21023216db7a4dfc8b0926c608162a81828e06622000a4d2c34e87ac1de8c9cc293eac
{
"asm": "023216db7a4dfc8b0926c608162a81828e06622000a4d2c34e87ac1de8c9cc293e OP_CHECKSIG",
"desc": "pk(023216db7a4dfc8b0926c608162a81828e06622000a4d2c34e87ac1de8c9cc293e)#24ru67fk",
"type": "pubkey",
"p2sh": "2N92fTTJNTJ8wMALQzKY44vcvGwgJy2BdL4",
"segwit": {
"asm": "0 203e1c96fc3083329aaa12e4deafdcd621ffc856",
"desc": "addr(tb1qyqlpe9huxzpn9x42ztjdat7u6cslljzkpukqtp)#wnu5wk85",
"hex": "0014203e1c96fc3083329aaa12e4deafdcd621ffc856",
"address": "tb1qyqlpe9huxzpn9x42ztjdat7u6cslljzkpukqtp",
"type": "witness_v0_keyhash",
"p2sh-segwit": "2MtGUckgdneKb2Hvk7d6GzZRhd3KHE9DtaD"
}
}
Then, if we can see "pubkey" in our "type" field, we are good to go. We should definitely avoid anything marked as "nonstandard", other outputs are usually fine, it depends, what exactly we need. But let's double check it, and decode a transaction:
decoderawtransaction 020000000138597989d9eb741c551d3c5949ef47330dbfbad99e85ee1e4aad4a5bf752a5a80100000000fdffffff0125310000000000002321023216db7a4dfc8b0926c608162a81828e06622000a4d2c34e87ac1de8c9cc293eac00000000
{
"txid": "04863e19ccf833b7d0e68f6e2173466cf97325ad1da3ba9d980c6ba05b25ede1",
"hash": "04863e19ccf833b7d0e68f6e2173466cf97325ad1da3ba9d980c6ba05b25ede1",
"version": 2,
"size": 95,
"vsize": 95,
"weight": 380,
"locktime": 0,
"vin": [
{
"txid": "a8a552f75b4aad4a1eee859ed9babf0d3347ef49593c1d551c74ebd989795938",
"vout": 1,
"scriptSig": {
"asm": "",
"hex": ""
},
"sequence": 4294967293
}
],
"vout": [
{
"value": 0.00012581,
"n": 0,
"scriptPubKey": {
"asm": "023216db7a4dfc8b0926c608162a81828e06622000a4d2c34e87ac1de8c9cc293e OP_CHECKSIG",
"desc": "pk(023216db7a4dfc8b0926c608162a81828e06622000a4d2c34e87ac1de8c9cc293e)#24ru67fk",
"hex": "21023216db7a4dfc8b0926c608162a81828e06622000a4d2c34e87ac1de8c9cc293eac",
"type": "pubkey"
}
}
]
}
As we can see, our "type" is "pubkey" in our output. Everything is fine, we can sign it.
signrawtransactionwithwallet "020000000138597989d9eb741c551d3c5949ef47330dbfbad99e85ee1e4aad4a5bf752a5a80100000000fdffffff0125310000000000002321023216db7a4dfc8b0926c608162a81828e06622000a4d2c34e87ac1de8c9cc293eac00000000" "[{\"txid\":\"a8a552f75b4aad4a1eee859ed9babf0d3347ef49593c1d551c74ebd989795938\",\"vout\":1,\"scriptPubKey\":\"001423d9fec5b46a9b3c9a9f0d8b080e50e0c6a3daaa\",\"amount\":0.00012704}]"
{
"hex": "0200000000010138597989d9eb741c551d3c5949ef47330dbfbad99e85ee1e4aad4a5bf752a5a80100000000fdffffff0125310000000000002321023216db7a4dfc8b0926c608162a81828e06622000a4d2c34e87ac1de8c9cc293eac02473044022073798fe1171b029d20a3f4a1646acc12124b6d365700cd6ac0863fe4c6624d9f02204e9169296522dff46815a5e50b4e55cce47699f6d60b31ff696a4de5d8dbfd95012103aafc2a07508a54c90be4d844569f9746f5d247d153b1784e93277410cf5bd50a00000000",
"complete": true
}
Then, we can decode it once more, to double check everything, mainly related to fees, if we didn't know, what to put there before:
decoderawtransaction 0200000000010138597989d9eb741c551d3c5949ef47330dbfbad99e85ee1e4aad4a5bf752a5a80100000000fdffffff0125310000000000002321023216db7a4dfc8b0926c608162a81828e06622000a4d2c34e87ac1de8c9cc293eac02473044022073798fe1171b029d20a3f4a1646acc12124b6d365700cd6ac0863fe4c6624d9f02204e9169296522dff46815a5e50b4e55cce47699f6d60b31ff696a4de5d8dbfd95012103aafc2a07508a54c90be4d844569f9746f5d247d153b1784e93277410cf5bd50a00000000
{
"txid": "04863e19ccf833b7d0e68f6e2173466cf97325ad1da3ba9d980c6ba05b25ede1",
"hash": "3733cc23d8cf95965832032dede4ad2527874299040bd26d40736d559d23dd18",
"version": 2,
"size": 204,
"vsize": 123,
"weight": 489,
"locktime": 0,
"vin": [
{
"txid": "a8a552f75b4aad4a1eee859ed9babf0d3347ef49593c1d551c74ebd989795938",
"vout": 1,
"scriptSig": {
"asm": "",
"hex": ""
},
"txinwitness": [
"3044022073798fe1171b029d20a3f4a1646acc12124b6d365700cd6ac0863fe4c6624d9f02204e9169296522dff46815a5e50b4e55cce47699f6d60b31ff696a4de5d8dbfd9501",
"03aafc2a07508a54c90be4d844569f9746f5d247d153b1784e93277410cf5bd50a"
],
"sequence": 4294967293
}
],
"vout": [
{
"value": 0.00012581,
"n": 0,
"scriptPubKey": {
"asm": "023216db7a4dfc8b0926c608162a81828e06622000a4d2c34e87ac1de8c9cc293e OP_CHECKSIG",
"desc": "pk(023216db7a4dfc8b0926c608162a81828e06622000a4d2c34e87ac1de8c9cc293e)#24ru67fk",
"hex": "21023216db7a4dfc8b0926c608162a81828e06622000a4d2c34e87ac1de8c9cc293eac",
"type": "pubkey"
}
}
]
}
As we can see, our "vsize" is 123, which means if we want to send our transaction with one satoshi per virtual byte fee, then we can subtract 123 satoshis from our output. As I said previously, usually I put the full amount first, then create and sign my transaction, then read the amount of virtual bytes, and then do it once more with a proper fee. And, as you can see, this "txid" and "hash" matches exactly with what you can see in testnet.
See and compare:
https://mempool.space/testnet/api/tx/04863e19ccf833b7d0e68f6e2173466cf97325ad1da3ba9d980c6ba05b25ede1/hex0200000000010138597989d9eb741c551d3c5949ef47330dbfbad99e85ee1e4aad4a5bf752a5a80100000000fdffffff0125310000000000002321023216db7a4dfc8b0926c608162a81828e06622000a4d2c34e87ac1de8c9cc293eac02473044022073798fe1171b029d20a3f4a1646acc12124b6d365700cd6ac0863fe4c6624d9f02204e9169296522dff46815a5e50b4e55cce47699f6d60b31ff696a4de5d8dbfd95012103aafc2a07508a54c90be4d844569f9746f5d247d153b1784e93277410cf5bd50a00000000
2. How would I claim the unspent transition to "only" a public key - in practice?
Spending from P2PK is similar, you just use different "scriptPubKey" when you specify, what should be signed, and put "2321...ac", instead of putting the script related to other address types. Then, the Core client will sign it, and you can broadcast it directly from your node, or by using any online tool, for example this one:
https://live.blockcypher.com/btc-testnet/pushtx/