text:
Is the Ouroboros Praos protocol proprietary?
The slots and epochs section of the Cardano Stake Pool Course states that the Ouroboros Praos protocol is proprietary.
Is this correct and, if so, is there a reason why this central part of the implementation needs to be proprietary?

Great catch! I have no idea how the word "proprietary" found its way in there. It's wrong, of course. I've just merged your pull request. BTW we moved this old course to the new developer portal that is being built. A lot of things are already improved, but if someone wants to contribute to the SPO category, please get in touch with me.

@adatainment I'd be interested in contributing.  Also - it would be good to see whether Chris Moreton's fork of plutus-pioneer-program can be merged, he is doing a great job of documenting the lectures: https://plutus-pioneer-program.readthedocs.io/en/latest/

That is not correct!
The ledger specifications are licensed under Apache License 2.0 and the paper is also open to public.

To be fair, the source states "The Cardano blockchain uses the proprietary Ouroboros Praos protocol to facilitate consensus on the chain."

Yes, the source is wrong. Or probably the wording is wrong.

I've created an issue here to get the source corrected

And the CF merged it right away! CF rocks.


text:
Poly Network attack - lessons for Plutus devs?
Over on Twitter, @kelvinfichter gave an analysis (included below) of the recent Poly Network hack.
Without any of the benefits of hindsight, are there reasons why the exploit would have been less likely to occur in Plutus on Cardano?

Poly has this contract called the EthCrossChainManager. It's basically a privileged contract that has the right to trigger messages from another chain. It's a pretty standard thing for cross-chain projects.
There's this function verifyHeaderAndExecuteTx that anyone can call to execute a cross-chain transaction. Basically it:

Verifies that the block header is correct by checking signatures (seems the other chain was a poa sidechain or something) and... then
Checks that the transaction was included within that block with a Merkle proof. Here's the code, it's pretty simple: EthCrossChainManager.sol#L127

One of the last things the function does is call _executeCrossChainTx, which actually makes the call to the target contract. Here's where the critical flaw sits.
Poly checks that the target is a contract EthCrossChainManager.sol#L185. But Poly forgot to prevent users from calling a very important target... the EthCrossChainData contract: EthCrossChainData.sol.
Why is this target so important? It keeps track of the list of public keys that authenticate data coming from the other chain. If you can modify that list, you don't even need to hack private keys. You just set the public keys to match your own private keys. See here for where that list is tracked: EthCrossChainData.sol#L22.
So someone realized that they could send an cross-chain message directly to the EthCrossChainData contract.
What good does that do them? Well, guess which contracted owned the EthCrossChainData contract... yep. The EthCrossChainManager. By sending this cross-chain message, the user could trick the EthCrossChainManager into calling the EthCrossChainData contract, passing the onlyOwner check.
Now the user just had to craft the right data to be able to trigger the function that changes the public keys. Link to that function here: EthCrossChainData.sol#L45.
The only remaining challenge was to figure out how to make the EthCrossChainManager call the right function. Now comes a little bit of complexity around how Solidity picks which function you're trying to call.
The first four bytes of transaction input data is called the "signature hash" or "sighash" for short. It's a short piece of information that tells a Solidity contract what you're trying to do. The sighash of a function is calculated by taking the first four bytes of the hash of "()".
For example, the sighash of the ERC20 transfer function is the first four bytes of the hash of transfer(address,uint256). Poly's contract was willing to call any contract. However, it would only call the contract function that corresponded to the following sighash: Errr but wait... _method here was user input.
All the attacker had to do to call the right function was figure out some value for _method that, when combined with those other values and hashed, had the same leading four bytes as the sighash of our target function.
With just a little bit of grinding, you can easily find some input that produces the right sighash. You don't need to find a full hash collision, you're only checking the first four bytes.
So is this theory correct? Well... here's the actual sighash of the target function:
> ethers.utils.id ('putCurEpochConPubKeyBytes(bytes)').slice(0, 10)
'0x41973cd9'`

And the sighash that the attacker crafted...
> ethers.utils.id ('f1121318093(bytes,bytes,uint64)').slice(0, 10)
'0x41973cd9'

Fantastic. No private key compromise required! Just craft the right data and boom... the contract will just hack itself!

The author then goes on to give lessons learned.
Do Plutus developers also need to learn from these lessons or are they specific to Solidity?

One of the biggest design lessons that people need to take away from this is: if you have cross-chain relay contracts like this, MAKE SURE THAT THEY CAN'T BE USED TO CALL SPECIAL CONTRACTS.
The EthCrossDomainManager shouldn't have owned the EthCrossDomainData contract. Separate concerns.
If your contract absolutely need to have special privileges like this, make sure that users can't use cross-chain messages to call those special contracts.
And just for good measure, here's the function to trigger a cross-chain message: EthCrossChainManager.sol#L91. Nothing here prevents you from sending a message to the EthCrossChainData contract.

@kelvinfichter also gives a simplified summary of the attack: https://twitter.com/kelvinfichter/status/1425290462076747777

Here's a link to Charles Hoskinson talking about the Cardano/Plutus approach back in March 2019: https://youtube.com/watch?v=f-rqaTLwWgs&t=4483s

This is a very broad question but here's what I think regarding this topic.
Without any of the benefits of hindsight, are there reasons why the exploit would have been less likely to occur in Plutus on Cardano?
First of all, this could have happened on Cardano too. As Charles said in his recent update:

This is not to say that hacks won't happen on Cardano, it will!
(...)
The hacks will occur in uncertified software. Applications that are not rigorously debugged or checked.
(...)
You can't control people maliciously or incompetently writing software that can create problems.
But the existence of certified software against known standards and auditing means that the consumer can have a visual representation (...) that demonstartes the difference between something that is known and reliable and something that is unknown.

See: https://youtu.be/xSXSZ5xLpYI?t=665
What this essentially means is that a similar exploit could happen on Cardano, but it is less likely for certified smart contracts that have been audited. This will not give 100% guarantee that there are no vulnerabilities in the contract. Some vulnerability may be missed in the audit too, but the risk can be greatly reduced.
Do Plutus developers also need to learn from these lessons or are they specific to Solidity?
I'm no expert when it comes to cross chain relay contracts, but I would answer this question with yes. It's always good to know about possible vulnerabilities and if you ever come across some Plutus code that makes calls to other smart contracts, the polygon hack is something to remember: "Are there any special contracts that I should not be able to call here?". Knowing about these things can make you write better and more secure code.

It was those words from Charles' that prompted me to ask the question.
There is a strong narrative in the community that Cardano smart contracts are going to be more secure. Given that solidity code could also be audited, I’m looking for specific evidence that may support the increased security narrative (e.g. tooling).
Otherwise there is perhaps a risk that the increased complexity/lack of familiarity with functional programming could actually make bugs more common on the The Island.

Haskell is a functional programming language, which is well-suited for high-assurance code and programs that require a high degree of formal verification because every line of code can be mathematically proven to be correct. This is one of the main advantages Plutus smart contracts have in comparison to e.g. Solidity. However, there is a difference between mathematically correct and secure. Plutus can't protect you from making mistakes like getting your access rights wrong as in the polygon example.

[In short]
"Things can go wrong in any software" is a statement that misses a mammoth fact. The probability of occurrence can vary on an astronomical scale, like the probability of a bug in a Javascript program( written by me in college) and the code driving the Curiosity rover. There have been bugs even in spacefaring vehicles that had caused catastrophic accidents like thee Flight 501 Failure. It may not be prudent to compare them at any level. Cardano is written in a Functional Programming language, Haskell, which has existed in the academic world for 30 years. The functional programming paradigm prevents [make it impossible] for programmers to make stupid mistakes and, on top of it, adds formal verification that makes the software space grade. Therefore if we have to follow the human scale and not some astronomical scale, we can say Cardano will not face hacks like what these mushroom networks face.
[In Detail]
The piece of the code from the Poly Network which had the vulnerability is referenced below.

Analysis
There are loops, jumps, and variables. The code can exist in various states. And it becomes impossible to test the code in all the possible states. After learning Haskell and Plutus, I can say with certainty loops, backward and forward jumps, and variables are the sources of all problems. Now for any new programmer, these are the first three steps that are taught. When I started learning Haskel, it was unbelievable that it is possible to program without these basic constructs. Haskell was heavily used by the Math community, which defines function as one input that gives one output irrespective of the date, time, or places it is executed. Everyone knows the square root of 2, but try calculating in C/C++/Java, depending on the floating-point implementation in a particular computer, the result varies by tiny amounts. However, due to the compounding effect of software, these tiny changes add up leading to a noticeable difference downstream. People working in Digital Signal Processing can vouch will vouch for this issue. Like the duration of a second determined by the pendulum clock with a temperature change.
Haskell is based on purity and has no variables and loops. It aims to achieve a lookup table-like behavior in which the values are calculated and pre-stored. Lookup table-like behavior prevents change in output due to state change. The functions are written in Haskell behave like mathematical functions. It goes to great lengths to achieve purity resulting in deterministic behavior. For example, see the following codeTake From
function main():
print assemble(3)
function assemble(x):
  var y = 0
  var s = “”
  do until (y > x)
    s += y++
  loop
  return s

and same logic implemented in Haskell
main = putStrLn $ assemble 3
assemble 0 = "0"
assemble y = assemble (y-1) ++ show y

Now it's not easy to appreciate Haskell's clarity unless we understand the type system. In the first code class, most of the languages accept any type of input to function assemble and try to convert to Int for adding and comparing. Haskell, does not allow writing codes without explicit type constraints. Haskell has a robust type system preventing many logical errors so common in languages like python and javascript. Even functions that have to subtract 2 from a given number can be a source of potential mistakes.
Now that's all good. But if there are no checks put in place, even the most saint of a person can become corrupt. Therefore all software is tested to ensure there is no error. The funny part is that it is some software that tests the other software, and the testing software can only generate fixed-size test scenarios. Therefore there is a need to reduce the surface required to test. The surface of testing is reduced by adopting functional programming. The added advantage is that it inherently helps in carrying out what is called "Formal Verification." Formal verification is an integral step in VLSI chip manufacturing. That is why there are very few "Bugs" in hardware chips. ( Have you ever come across any bug in the Intel I7 processor? now compare it with the number of bugs you had seen in Microsoft windows!!!.)

Formal Verification is the process of proving the correctness of systems (hardware/software/algorithms) using mathematical methods. Essentially it is used for ensuring, that something (be it a motherboard, a small chip, a library, a whole program, or an operating system) works as expected. For doing so, one formulates the “thing” mathematically, then formulates theorems that should or shouldn’t hold, and finally proves or disproves these theorems in mathematical ways.
When using the process in Software Development, it is often referred to as Formal Software Verification.

A pedestrian example is the square of an Integer is Integer. Math can prove this. We don't have to try all possible Integers and check that its square is an Integer. Programs that are written in functional languages can be formally verified. Unfortunately, a purely functional program will have no "so-called" side effects like any interaction with the outside world, like reading and writing into a network socket (used in the propagation of blocks in the blockchain). Therefore, Haskell has come up with very clever ways to permit side effects through strictly controlled mechanisms, preventing expansion of the surface required to carry out the testing.
These are some of the mechanisms which Cardano is using to ensure Secure Operation. Charles' Statement, "This is not to say that hacks won't happen on Cardano, it will! " is a fact. Still, comparative probability and the scale of impact on Risk Management are most likely to be astronomically minimal, compared to ad-hoc blockchains mushrooming out in the wild.

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

sort: votes


text:
Possible inconsistence data in db-sync
I've this query on Preprod:
SELECT
    ENCODE(TX.HASH, 'hex') as tx_hash,
    TX_OUT.INDEX,
    TX_OUT.ADDRESS_HAS_SCRIPT,
    ENCODE(TX_OUT.DATA_HASH,'hex') AS DATUM_HASH,
    SCRIPT.ID as script_id,
    TX_OUT.REFERENCE_SCRIPT_ID,
ENCODE(INLINE_DATUM.HASH,'hex') AS INLINE_DATUM_HASH
FROM TX_OUT
INNER JOIN TX ON TX.ID = TX_OUT.TX_ID
LEFT JOIN "script" ON "script"."hash" = "tx_out"."payment_cred"
LEFT JOIN "datum" AS "inline_datum" ON "inline_datum"."id" =
"tx_out"."inline_datum_id"
WHERE TX.HASH =
DECODE('8502fe3617b70d12fc65c8c17dab8483f5a7f847e0fba0376fe7abacf4773262','hex')
AND TX_OUT.INDEX = 3;

Where I'm getting some info about a specific UTxO. The result is this:
 tx_hash                                                          | index | address_has_script |                            datum_hash                            | script_id | reference_script_id |                        inline_datum_hash
------------------------------------------------------------------+-------+--------------------+------------------------------------------------------------------+-----------+---------------------+------------------------------------------------------------------
 8502fe3617b70d12fc65c8c17dab8483f5a7f847e0fba0376fe7abacf4773262 |     3 | f                  | 93892d0c469bd1228f0e94621d3101e755523e97ea0a837c9b509b1aeb9d8c42 |           |                     | 93892d0c469bd1228f0e94621d3101e755523e97ea0a837c9b509b1aeb9d8c42

You can see the UTxO doesn't have script address_has_script = f and left join to script table is null (LEFT JOIN "script" ON "script"."hash" = "tx_out"."payment_cred") resulting on empty column script_id. The same goes to column reference_script_id .
So we can we can assume no script is involved in this UTxO but we can see it has data_hash and according to db-sync schema doc:

You can also notice the UTxO has inline datum (column inline_datum_hash in the query) which value is the same as data_hash. I know strictly speaking having data_hash doesn't mean it must have a script but I just cannot understand this UTxO.
Why data_hash is the same as inline_datum_hash, and what does it means?

data_hash is always expected to be the same as the hash of the referenced inline_datum_hash. The existence of the latter simply shows that the datum is in fact inlined.
About your other question, you're right that the ledger rules technically allow to create an output that has a datum even if it's not locked by a script. In this case, the output is unspendable.

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
cardano-db-sync different tx, same hash?
I'm listening for new records added on block table and have noticed that sometimes two blocks are added almost at the same time with basically the same info except for block hash (maybe a slot battle/rollback, since eventually one of the blocks gets removed?).
The thing is when asking for the block's transactions UTXOS the block got removed return transactions with the same hash that the one who finally stays on chain but the transaction inputs/outputs are different (empty in this case).
So essentially the process is the following:

New block gets added into dbsync
Get block info (pool, transactions)
Get block transactions utxos which are empty. Probably empty is just one case and the important here is the fact that the tx for the two blocks are different but has the same hash.
Another block gets added into dbsync
Repeat step 2
Get block transactions utxos which aren't empty but have the same tx hash of the one returned by previous block

How is this posible, I think blocks is ok that enter into dbsync and the get removed due to rollbacks/slot battles but why the two blocks ended up with different txs (inputs/outputs) but the same hash?.
here is an example:
// arrive time [2022-10-28 13:40:52 UTC]
block info:
{
    "id": "7956798",
    "hash": "4eafa57522c951c571ef7f1f4f6c834b033ad2183121e4a02c9fd6f46ab91b8f",
    "epoch_no": 372,
    "slot_no": "75398161",
    "epoch_slot_no": 57361,
    "block_no": 7941775,
    "previous_block": 7941774,
    "next_block": null,
    "slot_leader": "pool17kew7rtakc7g6qzydntann5umw08xq3ll2j7spk7en4kvff69fa",
    "size": 58863,
    "time": "2022-10-28T13:40:52.000Z",
    "tx_count": "36",
    "out_sum": "6189878553712",
    "fees": "11268611",
    "confirmations": 1,
    "op_cert": "bf9af4d99bb361e89db95bde6303f756d864f85142691f92d897bafd986df8a9",
    "vrf_key": "vrf_vk1ygptnml8rkgw9dmguft6dr8dnjaapk80lsynqdwzl9aap08qg6mslll3fc",
    "pool": {
        "pool_id": "pool17kew7rtakc7g6qzydntann5umw08xq3ll2j7spk7en4kvff69fa",
        "raw_id": "f5b2ef0d7db63c8d00446cd7d9ce9cdb9e73023ffaa5e806decceb66",
        "url": "https://bloompool.io/bloom-3.metadata.json",
        "hash": "3cdd486927f8819dadb60ad8e9be691b8ba0ffa94b0356c38fe031b8f55b905f",
        "name": "Bloom Three",
        "ticker": "BLOOM",
        "homepage": "https://bloompool.io/",
        "description": "Bloom is committed to providing top quality staking services to our delegates through low latency, 24/7 uptime, and the highest return on stake. Operated by bigpey."
    },
    "transactions": [
        {
            "id": "53459220",
            "hash": "d868dc0cde2733aa5ee87db7b5ac2ae0e82aadec4aff71ee70d8e95cbf330307",
            "block_id": "7956798",
            "block_index": 25,
            "out_sum": "107197930",
            "fee": "183849",
            "deposit": "0",
            "size": 642,
            "invalid_before": null,
            "invalid_hereafter": "75408970",
            "valid_contract": true,
            "script_size": 0,
            "outputs": [],
            "inputs": []
        }
    ]
}

// arrive time [2022-10-28 13:40:53 UTC]
block info:
{
    "id": "7956799",
    "hash": "4d8296d03f2a0a471a16e34f2204026ac3c82311dfa2569fbb7f680e4cf3e66b",
    "epoch_no": 372,
    "slot_no": "75398161",
    "epoch_slot_no": 57361,
    "block_no": 7941775,
    "previous_block": 7941774,
    "next_block": null,
    "slot_leader": "pool1ddg6t2h9kj6lqlec4ncjs945lzj43m3ggrgdhf5sgzhtygpkznz",
    "size": 58863,
    "time": "2022-10-28T13:40:52.000Z",
    "tx_count": "36",
    "out_sum": "6189878553712",
    "fees": "11268611",
    "confirmations": 1,
    "op_cert": "d5b849f9757cd2ef60c883b092a7e985d27c22f89aac7648b13d3cfd4cce4737",
    "vrf_key": "vrf_vk1m5tnjq3exhpu8mfcy6rl5xe5jedd8adzx6n5syju3vj8p5yhfels900hls",
    "pool": {
        "pool_id": "pool1ddg6t2h9kj6lqlec4ncjs945lzj43m3ggrgdhf5sgzhtygpkznz",
        "raw_id": "6b51a5aae5b4b5f07f38acf12816b4f8a558ee2840d0dba69040aeb2",
        "url": "https://fairpool.eu/fair01.json",
        "hash": "8127f98bbad5af53a473e609d11e90f4135c2ae8cc86f27fafada12681a25d37",
        "name": "Fair Pool #01",
        "ticker": "FAIR",
        "homepage": "https://fairpool.eu",
        "description": "Highly available pool with a fair margin of 0.5%"
    },
    "transactions": [
        {
            "id": "53459256",
            "hash": "d868dc0cde2733aa5ee87db7b5ac2ae0e82aadec4aff71ee70d8e95cbf330307",
            "block_id": "7956799",
            "block_index": 25,
            "out_sum": "107197930",
            "fee": "183849",
            "deposit": "0",
            "size": 642,
            "invalid_before": null,
            "invalid_hereafter": "75408970",
            "valid_contract": true,
            "script_size": 0,
            "outputs": [
                {
                    "address": "addr1qydesz3sg492xwwynmv9hq4jn5t9fw4gz9gm8z7vxzzssa5m4mchcz7v3u7xrhssl83yah25vxgcjahdlp5u03t3sd2sx48u9r",
                    "hash": "d868dc0cde2733aa5ee87db7b5ac2ae0e82aadec4aff71ee70d8e95cbf330307",
                    "index": 1,
                    "value": "72197930",
                    "smart_contract": false,
                    "assets": [
                        {
                            "quantity": "1",
                            "policy_id": "b7761c472eef3b6e0505441efaf940892bb59c01be96070b0a0a89b3",
                            "asset_name": "CardanoWarriorsIslands5933",
                            "fingerprint": "asset1mnj2sgz8jufya0t9q3ccv8k5xxzsmwafzcvptc"
                        },
                        {
                            "quantity": "1",
                            "policy_id": "b7761c472eef3b6e0505441efaf940892bb59c01be96070b0a0a89b3",
                            "asset_name": "CardanoWarriorsIslands6359",
                            "fingerprint": "asset154fae8j77qnn99ku6k507h5plltrfmey9ap4ff"
                        },
                        {
                            "quantity": "1",
                            "policy_id": "b7761c472eef3b6e0505441efaf940892bb59c01be96070b0a0a89b3",
                            "asset_name": "CardanoWarriorsIslands4121",
                            "fingerprint": "asset13ul3yk367rgsn6jn9dcyflm6vel4rf0gns86kr"
                        },
                        {
                            "quantity": "1",
                            "policy_id": "b7761c472eef3b6e0505441efaf940892bb59c01be96070b0a0a89b3",
                            "asset_name": "CardanoWarriorsIslands1482",
                            "fingerprint": "asset1cwllcee0vm2630skuxhnkqchz8rel2qpl0nxwy"
                        },
                        {
                            "quantity": "1",
                            "policy_id": "b7761c472eef3b6e0505441efaf940892bb59c01be96070b0a0a89b3",
                            "asset_name": "CardanoWarriorsIslands5324",
                            "fingerprint": "asset1wr6uxxamarkwmg5thf0f0dmwy06r7trse3xwp2"
                        },
                        {
                            "quantity": "1",
                            "policy_id": "b7761c472eef3b6e0505441efaf940892bb59c01be96070b0a0a89b3",
                            "asset_name": "CardanoWarriorsIslands5160",
                            "fingerprint": "asset13pk5cux9xue205w52vjl66xgu428tz63rhn4u3"
                        },
                        {
                            "quantity": "1",
                            "policy_id": "b7761c472eef3b6e0505441efaf940892bb59c01be96070b0a0a89b3",
                            "asset_name": "CardanoWarriorsIslands5682",
                            "fingerprint": "asset1wmw0pw6ft3f5myajkvxfwd5d884u9hhqj49dhz"
                        },
                        {
                            "quantity": "1",
                            "policy_id": "b7761c472eef3b6e0505441efaf940892bb59c01be96070b0a0a89b3",
                            "asset_name": "CardanoWarriorsIslands1990",
                            "fingerprint": "asset1ha6at2s482re94tqazh5hlq28tv9nu6z4t3jwx"
                        },
                        {
                            "quantity": "1",
                            "policy_id": "b7761c472eef3b6e0505441efaf940892bb59c01be96070b0a0a89b3",
                            "asset_name": "CardanoWarriorsIslands5777",
                            "fingerprint": "asset122ue962qgvy3kc0qazlpn2ljdnlsdczl8l7a9t"
                        },
                        {
                            "quantity": "1",
                            "policy_id": "b7761c472eef3b6e0505441efaf940892bb59c01be96070b0a0a89b3",
                            "asset_name": "CardanoWarriorsIslands4925",
                            "fingerprint": "asset18lhkp5al2xs5zu5pq7zjehymnne8md5ypy7nhp"
                        },
                        {
                            "quantity": "1",
                            "policy_id": "b7761c472eef3b6e0505441efaf940892bb59c01be96070b0a0a89b3",
                            "asset_name": "CardanoWarriorsIslands7245",
                            "fingerprint": "asset1usc3r3rmthdpgs3894z6s8vc926vwjcxzd7te2"
                        },
                        {
                            "quantity": "1",
                            "policy_id": "b7761c472eef3b6e0505441efaf940892bb59c01be96070b0a0a89b3",
                            "asset_name": "CardanoWarriorsIslands3366",
                            "fingerprint": "asset1mua39yqstznzxwscuql2krmrayh0f7achj0qzx"
                        }
                    ]
                },
                {
                    "address": "addr1v97783v9dgj5vh6xlgwxazmgem2mpm0lz90vmgjs0kpz24sjc0usf",
                    "hash": "d868dc0cde2733aa5ee87db7b5ac2ae0e82aadec4aff71ee70d8e95cbf330307",
                    "index": 0,
                    "value": "35000000",
                    "smart_contract": false,
                    "assets": []
                }
            ],
            "inputs": [
                {
                    "address": "addr1q8j27e5gt6jwy3nqx9x2g85c5zmwlfdvqnv3v9xer2dymh5m4mchcz7v3u7xrhssl83yah25vxgcjahdlp5u03t3sd2s86ucr3",
                    "hash": "9589e00ac142b8a42813efc01da95f52fe8d3cac5263ef7d4888e02a072b250b",
                    "index": 1,
                    "value": "107381779",
                    "smart_contract": false,
                    "assets": [
                        {
                            "quantity": "1",
                            "policy_id": "b7761c472eef3b6e0505441efaf940892bb59c01be96070b0a0a89b3",
                            "asset_name": "CardanoWarriorsIslands5160",
                            "fingerprint": "asset13pk5cux9xue205w52vjl66xgu428tz63rhn4u3"
                        },
                        {
                            "quantity": "1",
                            "policy_id": "b7761c472eef3b6e0505441efaf940892bb59c01be96070b0a0a89b3",
                            "asset_name": "CardanoWarriorsIslands4121",
                            "fingerprint": "asset13ul3yk367rgsn6jn9dcyflm6vel4rf0gns86kr"
                        },
                        {
                            "quantity": "1",
                            "policy_id": "b7761c472eef3b6e0505441efaf940892bb59c01be96070b0a0a89b3",
                            "asset_name": "CardanoWarriorsIslands3366",
                            "fingerprint": "asset1mua39yqstznzxwscuql2krmrayh0f7achj0qzx"
                        },
                        {
                            "quantity": "1",
                            "policy_id": "b7761c472eef3b6e0505441efaf940892bb59c01be96070b0a0a89b3",
                            "asset_name": "CardanoWarriorsIslands5777",
                            "fingerprint": "asset122ue962qgvy3kc0qazlpn2ljdnlsdczl8l7a9t"
                        },
                        {
                            "quantity": "1",
                            "policy_id": "b7761c472eef3b6e0505441efaf940892bb59c01be96070b0a0a89b3",
                            "asset_name": "CardanoWarriorsIslands5324",
                            "fingerprint": "asset1wr6uxxamarkwmg5thf0f0dmwy06r7trse3xwp2"
                        },
                        {
                            "quantity": "1",
                            "policy_id": "b7761c472eef3b6e0505441efaf940892bb59c01be96070b0a0a89b3",
                            "asset_name": "CardanoWarriorsIslands6359",
                            "fingerprint": "asset154fae8j77qnn99ku6k507h5plltrfmey9ap4ff"
                        },
                        {
                            "quantity": "1",
                            "policy_id": "b7761c472eef3b6e0505441efaf940892bb59c01be96070b0a0a89b3",
                            "asset_name": "CardanoWarriorsIslands7245",
                            "fingerprint": "asset1usc3r3rmthdpgs3894z6s8vc926vwjcxzd7te2"
                        },
                        {
                            "quantity": "1",
                            "policy_id": "b7761c472eef3b6e0505441efaf940892bb59c01be96070b0a0a89b3",
                            "asset_name": "CardanoWarriorsIslands4925",
                            "fingerprint": "asset18lhkp5al2xs5zu5pq7zjehymnne8md5ypy7nhp"
                        },
                        {
                            "quantity": "1",
                            "policy_id": "b7761c472eef3b6e0505441efaf940892bb59c01be96070b0a0a89b3",
                            "asset_name": "CardanoWarriorsIslands5682",
                            "fingerprint": "asset1wmw0pw6ft3f5myajkvxfwd5d884u9hhqj49dhz"
                        },
                        {
                            "quantity": "1",
                            "policy_id": "b7761c472eef3b6e0505441efaf940892bb59c01be96070b0a0a89b3",
                            "asset_name": "CardanoWarriorsIslands1482",
                            "fingerprint": "asset1cwllcee0vm2630skuxhnkqchz8rel2qpl0nxwy"
                        },
                        {
                            "quantity": "1",
                            "policy_id": "b7761c472eef3b6e0505441efaf940892bb59c01be96070b0a0a89b3",
                            "asset_name": "CardanoWarriorsIslands5933",
                            "fingerprint": "asset1mnj2sgz8jufya0t9q3ccv8k5xxzsmwafzcvptc"
                        },
                        {
                            "quantity": "1",
                            "policy_id": "b7761c472eef3b6e0505441efaf940892bb59c01be96070b0a0a89b3",
                            "asset_name": "CardanoWarriorsIslands1990",
                            "fingerprint": "asset1ha6at2s482re94tqazh5hlq28tv9nu6z4t3jwx"
                        }
                    ]
                }
            ]
        }
    ]
}

I'm listening for new records added on block table and have noticed that sometimes two blocks are added almost at the same time with basically the same info except for block hash.

Yes this is a result of a rollback which is often (but not always) a result of a slot battle. As part of this rollback, db-sync will end up deleting one of these blocks.

... why the two blocks ended up with different txs (inputs/outputs) but the same hash?.

But the hashes are not the same. For the first its 4eafa57522c951c571ef7f1f4f6c834b033ad2183121e4a02c9fd6f46ab91b8f and for the second its 4d8296d03f2a0a471a16e34f2204026ac3c82311dfa2569fbb7f680e4cf3e66b. The both start with a 4 but are not the same.

Hi, thanks for the quick reply. About the same hash I was referring to the tx hash no block hash. It seems the issue is some gaps between my logic fetching the data and the slot battle/rollback happening.

Two blocks targeting the same block height are likely to have predominantly the same set of transactions. If one of these  blocks gets rolled back, all the transactions in that block will also be rolled back.


text:
Aiken onchain check original message wrapped in CIP30 signData signed message
I've a message that will be signed by user's wallets, the thing is wallets follow CIP30 for signing a message (payload in Sig_structure below), meaning the final signed message is like this:
Sig_structure = [
       context : "Signature" / "Signature1" / "CounterSignature",
       body_protected : empty_or_serialized_map,
       ? sign_protected : empty_or_serialized_map,
       external_aad : bstr,
       payload : bstr
   ]

So the original message gets wrapped inside Sig_structure. On chain I'm using verify_signature to validate the user signed that message, the thing is I want to make sure the message I'm verifying is actually wrapping the original message otherwise I'm just validating the wallet sign a message but I don't know if it's actually a wrapped of the original one.
Signed message (Sig_structure) is a CBOR, so I'd like to know what options Aiken provides (if there is any) to make that kind of verification. I was thinking on instead of parsing (I haven't found a way to parse CBOR data) that CBOR signed message, going the other way around and create a CBOR using cbor.serialise and then compare both strings. The problem is I can't find a way to put a plain text in the CBOR. Here is my attempt so far:
  let data =
    [
      "Signature1", // the context
      #"a201276761646472657373581d603dce7844f36b23b8c3f90afba40aa188e7f1d3f6e8acd1d544ed1da9", // the body_protected, it's a map for algorithm and address { 1: -8, "address": "..." }
      #"", // external_aad is empty
      #"4d494e547c000000000000000000000000000000000000000000000000000000002e666f6f", // original message
    ]
  trace bytearray.to_hex(serialise(data))

which generate this CBOR:
9f4a5369676e617475726531582aa201276761646472657373581d603dce7844f36b23b8c3f90afba40aa188e7f1d3f6e8acd1d544ed1da94058254d494e547c000000000000000000000000000000000000000000000000000000002e666f6fff

Structure:
9F                                      # array(*)
   4A                                   # bytes(10)
      5369676E617475726531              # "Signature1"
   58 2A                                # bytes(42)
      A201276761646472657373581D603DCE7844F36B23B8C3F90AFBA40AA188E7F1D3F6E8ACD1D544ED1DA9 # "\xA2\u0001'gaddressX\u001D`=\xCExD\xF3k#\xB8\xC3\xF9\n\xFB\xA4\n\xA1\x88\xE7\xF1\xD3\xF6\xE8\xAC\xD1\xD5D\xED\u001D\xA9"
   40                                   # bytes(0)
                                        # ""
   58 25                                # bytes(37)
      4D494E547C000000000000000000000000000000000000000000000000000000002E666F6F # "MINT|\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000.foo"
   FF                                   # primitive(*)

[
  h'5369676E617475726531',
  h'A201276761646472657373581D603DCE7844F36B23B8C3F90AFBA40AA188E7F1D3F6E8ACD1D544ED1DA9',
  h'',
  h'4D494E547C000000000000000000000000000000000000000000000000000000002E666F6F'
]

Which is slightly different from the one coming from CIP30:
846a5369676e617475726531582aa201276761646472657373581d603dce7844f36b23b8c3f90afba40aa188e7f1d3f6e8acd1d544ed1da94058254d494e547c000000000000000000000000000000000000000000000000000000002e666f6f

Structure:
84                                      # array(4)
   6A                                   # text(10)
      5369676E617475726531              # "Signature1"
   58 2A                                # bytes(42)
      A201276761646472657373581D603DCE7844F36B23B8C3F90AFBA40AA188E7F1D3F6E8ACD1D544ED1DA9 # "\xA2\u0001'gaddressX\u001D`=\xCExD\xF3k#\xB8\xC3\xF9\n\xFB\xA4\n\xA1\x88\xE7\xF1\xD3\xF6\xE8\xAC\xD1\xD5D\xED\u001D\xA9"
   40                                   # bytes(0)
                                        # ""
   58 25                                # bytes(37)
      4D494E547C000000000000000000000000000000000000000000000000000000002E666F6F # "MINT|\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000.foo"

[
  "Signature1",
  h'A201276761646472657373581D603DCE7844F36B23B8C3F90AFBA40AA188E7F1D3F6E8ACD1D544ED1DA9',
  h'',
  h'4D494E547C000000000000000000000000000000000000000000000000000000002E666F6F'
]

You can see "Signature1" is hex encoded when using cbor.serialise and also is adding an extra FF at the end
   FF                                   # primitive(*)

Even though I ended up having the same CBOR that isn't a good approach since wallets can decide to add/remove some optional fields in Sig_structure breaking this logic.


text:
Query latest pool of stake address from cardano db sync
How do i query latest pool of all the stake address when using cardano db sync?

The following will give you a list of pools with associated stake addresses.
  SELECT ph.view AS "pool_id", sa.view AS "stake_address"
  FROM stake_address sa
    JOIN stake_registration sr ON (sr.addr_id = sa.id)
    JOIN delegation d ON (d.addr_id = sa.id)
    JOIN pool_hash ph ON (ph.id = d.pool_hash_id)
  WHERE d.id = (
      SELECT MAX(id)
      FROM delegation
      WHERE addr_id = sa.id
    )
    AND sr.tx_id = (
      SELECT MAX(tx_id)
      FROM stake_registration
      WHERE addr_id = sa.id
    )
    AND (
      sr.tx_id > (
        SELECT COALESCE(MAX(tx_id), 0) -- handles IS NULL option so we don't have to run that query again
        FROM stake_deregistration
        WHERE addr_id = sa.id
      )
    )
    ORDER by pool_id;

Which will result.
                         pool_id                          |                        stake_address
----------------------------------------------------------+-------------------------------------------------------------
 pool100wj94uzf54vup2hdzk0afng4dhjaqggt7j434mtgm8v2gfvfgp | stake1u9nc4zs4wapwzg6lmrmc8uulngg5slphtd9zl8hzptsdhrcsph992
 pool1026f3pyjhxjafmtjyyny5ytuh2kraxakfa8eu5h844uv2upzxvq | stake1u9mmge8895vp5hsyutxuu0lhze5egj2ltszkqx9vtfwtc5c7llhe6
 pool1026f3pyjhxjafmtjyyny5ytuh2kraxakfa8eu5h844uv2upzxvq | stake1uykx3da7j9v0gp0ae2faxr27arlgfcrv4y980k0jgjemz8cy3m260
 pool1026f3pyjhxjafmtjyyny5ytuh2kraxakfa8eu5h844uv2upzxvq | stake1uxxqarsyyu6dt2c558qeza8fzwdsnqtkhdhts88gs8vy6sqfl3dq7
 pool1026f3pyjhxjafmtjyyny5ytuh2kraxakfa8eu5h844uv2upzxvq | stake1u8vygrzl9d3yfnf0scqx5vwe8yguyjyqljcrpy2tn0tq4pqffqv2d
 pool1026f3pyjhxjafmtjyyny5ytuh2kraxakfa8eu5h844uv2upzxvq | stake1uyp58nm4749e3dkdasyef52th308sytgx2j9yd7rl8c8efga46r7k
 pool1026f3pyjhxjafmtjyyny5ytuh2kraxakfa8eu5h844uv2upzxvq | stake1uxkxkdsehergfanuxu7p0rvdxkjflnllyhnjdrw7hudv5ush8nqlf
 pool1026f3pyjhxjafmtjyyny5ytuh2kraxakfa8eu5h844uv2upzxvq | stake1uxem4w0uuanqu0q9kedm250w0vfzfyylttf06kg4rn696jc6vj4kq
 pool1026f3pyjhxjafmtjyyny5ytuh2kraxakfa8eu5h844uv2upzxvq | stake1u9x3sppud2y3uztgzhq9qsq9wc8059fnqeaxelta92jjlmcneg6dg
 pool1026f3pyjhxjafmtjyyny5ytuh2kraxakfa8eu5h844uv2upzxvq | stake1ux5l7l829vjylmlmpj5jmlnwg9ryqatl5gjltvzlyhpq09qn874qt
 pool102kv4jtzs5cp2s58qa8esmdxc6awsu4a8smtlgkyylq7gvzgdwv | stake1uxzgxaygqmmus994yucrdwfgqg0ugn97pvlq7zeyzhhkhec8a2jm4
 pool102s2nqtea2hf5q0s4amj0evysmfnhrn4apyyhd4azcmsclzm96m | stake1u80u89wyha0ylkngfwdy9u9qermm64lpdfuy5uvjrfg8vvshahmgx

(...)


text:
Query all the transaction details from a given block using cardano db sync
Can someone help out with how can i query the transaction details from a block using cardano db sync table? I actually need fields like epoch no, date of transaction, stake address, pool and the amount of the given transaction? I was trying it from the delegation table, but i am having problem with finding the epoch no and if the amount for a given stake address is input or an output(-ve for outgoing and +ve for incoming amount for a given stake address).

Efficient manner is join.
select block.id as block_identifier,* from tx left join block on block.id=tx.block_index where tx.hash='\x{hash}';

Make sure you pay attention to not mixing ID fields.
Some variables not accurately named, a quick check should help you though. You'll need to login to your postgres instance and connect using \c cexplorer
Then type \dt+ to get tables. \d+ {tablename}

The schema docs (autogenerated) are at https://github.com/input-output-hk/cardano-db-sync/blob/master/doc/schema.md .


text:
Alonzo being a hard fork, will Daedalus support it automatically?
How should the users prepare for the upcoming Alonzo hard fork?
Will it be as simple as just updating the Daedalus wallet when it's out, or are there some precautious actions that we have to take (Like undelagating from the pools etc) ?

Users of Cardano will have nothing they need to do.
Cardano uses the Hard Fork Combinator which allows upgrades to the protocol while keeping all previous blocks from the previous eras.
https://docs.cardano.org/en/latest/explore-cardano/what-is-a-hard-fork-combinator.html#what-is-a-hard-fork-combinator
This process has taken place last year with Shelly that turned on the delegating system today.

Thank you so much.
It is relieving to know.


text:
Will ERC-20 converter support the legacy ERC-20 token itself?
I recently learned that Cardano is about to launch the Erc20 tokens swapping functionalities. This makes me really happy for multiple reasons since ETH had disappointed me in many aspects over the years (Been in crypto since 2013 and dealing with Eth since '15 - '16) So I'd like to get out of it as much as I can.
I'm currently wondering, if I'll be able to swap the Erc20s themselves?
Meaning; not any particular tokens that are built on Erc20 but the Erc20 standard token itself.
The reason I'm asking for is that I obtained some amounts of Erc20s around 2016 and was willing to forget about them for the long term, thinking that they were a good investment since it was pushed out to be a "standard", little did I know and I learned years after, that they ended up changing/updating the standard itself and not only there are now various more standards as well, but there is this old Erc20 and the new Erc20 now. This is one of the biggest let downs for me from the ETH ecosystem as I feel somewhat duped on the subject.
I've been researching the web for months now, on how to convert these old ones to the current version but the closest I got requires large amounts of gas / transaction fees. Feels almost not worth it, so I'm stuck with them like this.
So I am wondering (and hoping) if there will be an automated contract solution from Cardano to swap/convert/update these in relatively cheaper costs if not cost free?
The honest reasoning I have behind this, is I would assume that the developers would still need these tokens for various applications and perhaps some contracts would still be requiring the old versions of this ERC20 standard. So may be not exchanging or swapping them for their current value but perhaps fueling some backwards compatible smart contracts etc. I tend to refuse that this is not the case because otherwise the whole Ethereum ecosystem seems like an everchanging, evergrowing and evolving scam.
I know Cardano is relatively beyond this but having it's roots based on ETH I trust people here, would have some knowledge and guidance about this. Keeping in mind that ADA community seem mostly focused on solving these very issues which hurt the users and the investors.
I apologize for the lengthy post and  I thank everyone so much in advance to those who'd be willing to enlighten me on the subject.

This is a good question but I think converting is more for the developer converting their token(Smart Contract) to run on Cardano without requiring a full code rewrite as ERC20 contract is based on Solidity and wouid not be able to run on Cardano network so if you have a ERC20 smart contract project it can be converted to run on Cardano.

Thank you for your reply. I agree that this issue should concern the developers and not the user. That's why and where I feel betrayed by the ecosystem.
This whole issue shouldn't have been my problem and as an investor/user, I shouldn't have had to deal with this. That's why I'm counting on the Cardano team to save the day.

I had a similar user experience with the Golem project on ETH. I got lucky when the fee to convert the old to new for about $50 bucks. At times the price was as high as $400.
There isn't any talk about this particular issue with projects having a split ERC-20 token before moving to Cardano. That being said it should be possible to fix this however no matter the solution, anything on the ETH network will have to pay ETH fees.

ERC20 Price is currently at $0.04621 and ERC(OLD) is around 0.000039$
I invested in ERC20 and seeing this really scars me.
I wouldn't mind paying a fee for swapping this token for another, but paying a fee to "update" it just doesn't seem fair. Since it is "imposed" by the developers.
Isn't there some sort of a treasury like Cardano has, where the user's costs for "updating" their token contract is covered by the network automatically?
I just hope that the Cardano team comes along with a solution and saves people in this situation like myself.
Thank you for your reply by the way.


text:
Question about Daedalus deposit withdrawal
I'm willing to reorganize my wallets but as I read over here; https://cardano.stackexchange.com/a/555/1927 this feature was "removed" (?!) from the Daedalus wallet and I know that there's an open "feature-request" topic over here; https://github.com/input-output-hk/daedalus/pull/2351
But I was wondering if anyone had any knowledge on the subject, like when it's planned to be added or why was it removed in the first place etc?

Please re-formulate this question so that the viewer doesn't have to navigate to several other links to understand what question you're asking. It will make it more useful to people searching later.

Does this answer your question? Questions about Daedalus deposit withdrawal and delegation privacy?

@intrinsic-values please don't mark things as a duplicate of a closed question!

I will vote to close it as it is better addressed by request for clarification and/or detail in the question that is referenced in the body of the question.  @user3152883, I think you will have more success with your efforts here if you follow the guidance at [ask]


text:
About Daedalus (also ADA in general) delegation privacy
I'm feeling really uncomfortable about delegation privacy. No matter how many wallets/addresses I use to separate my funds people can use https://cardanoscan.io to see which addresses are delegated into which pools.
Even though it's not solid proof for who's the owner of those addresses, exchanges and pool owners can backtrack my delegation addresses and see into which other pools have been delegated relating to that account.
I feel very disturbed about this. I know there are some ways to separate staking address from receiving address and using only the receiving address hash output for transactions, using terminals and programming but I'm not a coder and was wondering if there are any future plans to implement such privacy features in a user friendly fashion into Daedalus?

I understand your issue, for privacy try using https://adalite.io/. They let you generate multiple Cardano Accounts that have their own stake keys. You can use this with hardwallets.
Now you can stake separately from the address you want to use for commerce.
I think this issue would be something that is down the road in the development.

Thank you so much for your response and showing an alternative wallet. I really appreciate it. But I rather stick to the official wallet and wait for an official update for it. Glad hear you think the issue would be addressed down the line, I just hope it's not way down.


text:
"plutusV2MintingPolicy" lookup not found by "balanceTx"
I am trying to mint some example tokens in offchain plutus code on tag v1.0.0-alpha1.
This is the OffChain code I am currently using:
mintFactoryToken :: Contract () MintFactorySchema Text ()
mintFactoryToken = do
  outRef <- getUnspentOutput
  pkh    <- ownFirstPaymentPubKeyHash
  o      <- fromJust <$> unspentTxOutFromRef outRef
  let
    !policy     = mintValidator outRef
    symbol     = scriptCurrencySymbol policy
    mintValue  = Value.singleton symbol contractDataTokenName 1 <> Value.singleton symbol chunkCreationTokenName 1
  Contract.logDebug outRef
  Contract.logDebug policy
  Contract.logDebug symbol
  Contract.logDebug mintValue
  let
    l          = Constraints.plutusV2MintingPolicy policy <>
                 Constraints.unspentOutputs (Map.singleton outRef o)
    constr     = Constraints.mustMintValue mintValue
  unbalanced <- Contract.mkTxConstraints @Any l constr
  Contract.logDebug @Text "Unbalanced"
  adjusted  <- Contract.adjustUnbalancedTx unbalanced
  Contract.logDebug @Text "adjusted"
  unsigned  <- Contract.balanceTx adjusted
  Contract.logDebug @Text "unsigned"
  signed    <- Contract.submitBalancedTx unsigned
  Contract.logDebug @Text "signed"
  --ledgerTx <- Contract.submitTxConstraintsWith @Void l constr
  Contract.awaitTxConfirmed $ getCardanoTxId signed
  Contract.logDebug @Text "signed"

But as soon as it reaches Contract.balanceTx adjusted I encounter the following error:
Slot 00001: *** CONTRACT STOPPED WITH ERROR: "\"WalletContractError (ValidationError (CardanoLedgerValidationError \\\"MissingScript (RdmrPtr Mint 0) (fromList [(RdmrPtr Mint 0,(Minting (PolicyID {policyID = ScriptHash \\\\\\\"2fcc3c79d2cb27a9784a7d3e69de5f1909406fcbc33567e6dd24288b\\\\\\\"}),Nothing,ScriptHash \\\\\\\"2fcc3c79d2cb27a9784a7d3e69de5f1909406fcbc33567e6dd24288b\\\\\\\"))])\\\"))\""

Do I have to do something special in order to get this to work or is this just not supported at the moment?
I've seen in the Relese Notes that some custom validation rules are used at the moment:

...

plutus-contract emulator has been updated to work with Babbage era types. However, the UTxO index in the emulator does not support transaction outputs with reference scripts and inline datums.
plutus-contract emulator uses the Babbage era validation rules from cardano-ledger. However, we continue to use our old custom validation rules which we plan to remove in the next alpha release in order to fully commit with cardano-ledger 's validation rules.

...

But I am not sure if this causes my problem or not.
Signatures of the OnChain code:
{-# INLINABLE validateMinting #-}
validateMinting :: TxOutRef -> BuiltinData -> BuiltinData -> ()
...

mintValidator :: TxOutRef -> MintingPolicy
mintValidator oRef = mkMintingPolicyScript
   ($$(Tx.compile [|| validateMinting ||]) `Tx.applyCode` Tx.liftCode oRef)

mintCurrencySymbol :: TxOutRef -> CurrencySymbol
mintCurrencySymbol = scriptCurrencySymbol . mintValidator

Can't see anything wrong with what you're doing. A lot has changed since v1.0.0-alpha1 so could you try with latest from next-node branch and see if it helps.

As james noted in a comment a simple update to the head of next-node resolved the issue. now tokens are minted correctly


text:
Is it possible to generate your own Cardano ADA private keys and public addresses externally and import it later for use into a wallet?
For ETH and BTH you can generate a private/public keys (secp256k1 Elliptical curve) and SHA-3 (Keccak) hashed public wallet address via code (Python, Java or what ever language) via an pure math algorithm externally then use that address in wallets for payment to cold storage.
Is it possible to generate keys/addresses for Cardano ADA this way in code externally without any interaction from any 3rd party wallet application (Daedalus, Yoroi), then import it later into a wallet when needed to be used for payment or redeeming from cold address storage?

There are a variety of projects within the IOHK Github repository that may give the correct level of interaction you desire. After some digging I think the cardano-addresses project would fulfill your needs.

As others stated above, yes you can. You will need the cardano-wallet or CLI from iohk but I wouldn't consider that 3rd party. There is actually an easy way to do it following Coin Cashew's How to Build a Cardano Stake Pool Guide
Go to Section 10. Setup Payment and Stake Keys. Then skip down and choose the Mnemonic Method. This will walk you through doing this.


text:
Daedalus on Ubuntu 20.04 cannot contact the network
I am unable to connect to the Daedalus mainnet for over four days now.  The time sync is correct, so that is not the issue.  Running Ubuntu 20.04, and have not had this problem for a very long time. I have tried countless times.

What have you done so far to try and work out the issue?  Do you have any errors or warnings in the logs?

No, but see my comment below.  I solved it, but not sure what actually solved it!  Thanks

Try reinstalling Ubuntu or Linux Mint then install again. It could be multiple things going on so reinstalling the OS for weird stuff can work. I use Linux mint without issues.

Hi, I rebooted my modem, rebooted my machine and it finally worked, but it took a long time to connect to the network.  So really I have no idea what it was, but it is working now.  cheers and thanks

Have you tied restarting the Cardano node within Daedalus? I have have flight running on Ubuntu with no issues. Once you reset the node walk away for a bit and come back and see if you've connected.

I think I did something like that.  Whatever I did it worked, and there was an issue, which the logs showed, but I am not sure what it was.  Works now though.  cheers

I'm sure there are many reasons why this might happen, but my last experience of this on Ubuntu (Pop OS) was when I was connected to a VPN. Disconnecting immediately solved the problem, so it's possible if you use a company VPN that the network traffic is being blocked for the wallet.

Thanks, I don't use a VPN, other than in browser.  I don't think I am going toknow what it was, but IOHK checked my logs and said there was an issue, I think maybe at their end, but seems ot be solved now.  cheers


text:
Query and extract NFT metadata from a cardano-node instance (without db-sync)
Is there a way to query NFTs and extract NFT metadata from a cardano-node instance without using db-sync?

No, the transactional metadata are not part of the ledger state.

Thanks for the reply. Then, is there a way to scan the ledger directly? Are any of the db-* binaries in the tarball able to this? I need something that doesn't require 40GB of RAM, so db-sync is not an option. And it also needs to be able to run independently, without external services. My last resort would be Carp.

Sadly, I do not think that information is stored anywhere by the cardano-node. Cardano-db-sync or tools like Blockfrost actually has to reply all the blocks to extract it. Try maybe looking at Kupo.

I didn't know Kupo, looks great. That could be a useful tool. In the meantime, I've been considering other approaches to make it work with db-sync and even Blockfrost. Thanks again!


text:
Registering policy ID programatically (pool.pm)
I'm seeing many NFT minting policies registered on pool.pm, and I noticed they can be registered manually there as well.
Is there a way to do this programmatically? And is this a pool.pm-specific thing, or is there some kind of central registry?

Welcome to the site!

Just open your network tools on yojr favorite browser and inspect the request which is made when submitting a script. Should be easy.

Yeah, that was kind of my last resort. I was just wondering if there was a more "official" way to do it, rather than hacking around it and risking things to be broken if Smaug decides to change their internal API.

No, there's no way to currently do this programmatically, and yes - this feature is specific to pool.pm.


text:
what is the ADA (Cardano crypto-currency) SDK?
I'am very new to the blockchain community and I have a new project that i'am starting to work on using the Cardano Blockchain and its crypto ADA.
I stumbeled upon the name "ADA SDK" and I tried to dig deeper and research it more but i can't find any clear information on what do you use it for exactly.
I know what is an SDK in general but what is an ADA SDK ?
Is it the development Kit you have to download to start working with ADA ? or what exactly ?
The few information that I found are that there an android/ios ada SDK that is used for a chatbot or something and I don't think it's the same thing i'm talking about or is it ?
I'm so sorry but I'am really confused is there anyone who could help me ? thank you !!

From my understanding, Cardano SDK is a set of libraries for different languages which should make it easier to integrate with Cardano. You can take a look here https://github.com/input-output-hk/adrestia


text:
Can the Validator ensure a certain Datum is sent by the Redeemer?
is it possible for a Validator to ensure that the redeemer pays some Value along with a certain Datum attached to it? Looking at the possible transaction methods on the ScriptContext, checks are only done on the Value and not the Datum. I see the DatumHash types but am not sure what it is used for.

Hope my answer was helpful. I'm not sure if you're overloading the term "Redeemer" (the redeemer data type vs the sender of that tx). I think I got what you were going for though. LMK if I can clarify.

The validator can ensure that a datum or multiple datums are included in the output.
Take the Uniswap clone in the plutus-use-cases for example:
The validateCreate method ensures that an updated Factory datum
Constraints.checkOwnOutputConstraint ctx (OutputConstraint (Factory $ lp : lps) $ unitValue usCoin)

and a new Pool datum
Constraints.checkOwnOutputConstraint ctx (OutputConstraint (Pool lp liquidity) $ valueOf lpCoinA outA <> valueOf lpCoinB outB <> unitValue c)

are included in the outputs.
Both of these are attached to some Value.

Oh gosh I didn't know there was a whole library on On-Chain Constraints. Thank you!
As for the term Redeemer, I believe the language used has been not-strict enough. So to my understanding, the person initiating the transaction is called the Redeemer, and he/she will supply a RedeemerType to the Validator to spend the underlying eUTXO.
Link to the On-Chain constraints library: [https://github.com/input-output-hk/plutus/blob/160d158c2679a72adfc8edf7a1c43a4b59189d99/plutus-ledger/src/Ledger/Constraints/OnChain.hs]

Yeah. The on-chain constraints are great and they compliment the off-chain constraints well. The more declarative the better :)


text:
Plutus Pioneer Program - Lecture #1- Cabal Build error
I started following the lectures on youtube and got this error when I try to build the English Auction
Warning: The build command is a part of the legacy v1 style of cabal usage.
Please switch to using either the new project style and the new-build command
or the legacy v1-build alias as new-style projects will become the default in
the next version of cabal-install. Please file a bug if you cannot replicate a
working v1- use case with the new-style commands.
For more information, see: https://wiki.haskell.org/Cabal/NewBuild
Resolving dependencies...
Warning: solver failed to find a solution:
Could not resolve dependencies:
[__0] trying: plutus-pioneer-program-week01-0.1.0.0 (user goal)
[__1] next goal: base (dependency of plutus-pioneer-program-week01)
[__1] rejecting: base-4.12.0.0/installed-4.1... (conflict:
plutus-pioneer-program-week01 => base^>=4.14.1.0)
[__1] fail (backjumping, conflict set: base, plutus-pioneer-program-week01)
After searching the rest of the dependency tree exhaustively, these were the
goals I've had most trouble fulfilling: plutus-pioneer-program-week01, base
Trying configure anyway.
Configuring plutus-pioneer-program-week01-0.1.0.0...
cabal: Encountered missing dependencies:
aeson -any,
base >=4.14.1.0 && <4.15,
playground-common -any,
plutus-contract -any,
plutus-ledger -any,
plutus-tx -any,
plutus-tx-plugin -any
tried to run nix-shell at the top-level directory of the plutus-repository but I couldn't. Got
Error: getting status of '/home/test/plutus/plutus-pioneer-program/default.nix': No such file or directory

I had a similar issue and solved it by running nix-shell in the plutus library, then navigating to the plutus-pioneer/code/week01 and running cabal update. I hope this helps!

I could run cabal update and cabal build. When I try to execute cabal run an error message saying that 'Cannot run the target '' which refers to the package plutus-pioneer-program-week01-0.1.0.0 because it does not contain any executables.' shows.

Ahh, I think you should be using cabal repl in the week01 folder. **note the lowercase w in week01. This folder should contain these files: cabal.project  hie.yaml  LICENSE  plutus-pioneer-program-week01.cabal  src

Hello Isaac, could you please tell me how can i get to the plutus library?

You can us "cd /nameofdirectory" in the terminal on linux. I would familiarize yourself with terminal commands and Vim :)

I had the similar problem, this recipe works for me:
Run nix-shell inside plutus project and move to plutus-pioneer-program/code/week01 directory from nix shell, then start cabal build.
UPD:
plutus-pioneer-program repo contains README with steps how to run plutus-playground, one of steps is to clone Plutus repo and to checkout it to the specific commit. Inside that Plutus directory you can run nix-shell and then go to pioneer directory.

How can i do that? when i try to run nix-shell  i get Error: getting status of '/home/test/plutus/plutus-pioneer-program/default.nix': No such file or directory ,  where is the plutus project? is it a file or a location? sry if it seems tooo silly !!!

Plutus repo it is mentioned in the Week #1 homework in the plutus-pioneer-program repo.

Thank you , so I must install this library using nix, as well as cabal before running cabal - build ?

Not exactly, you should just clone plutus repo, and every time when you want to run some code from pioneer program you should firstly run nix shell from plutus and go to desired project in that shell to run cabal commands.

I am new to nix, but my understanding is as follows:
Both the plutus and plutus-pioneer-program repos need to be extracted on disk. Check out the plutus commit of the coding week you want to work on (in cabal.project in root of week code folder).
Start all the nix-shell instances you require in the root of the plutus repository. I start 3: one each for playground server and client, and programming in Hashkell (cabal repl). For each shell you have to cd to the correct folder. This way all components are in sync.
Don't forget to set up the cache at the start.
I am really impressed how nix make this so easy.


text:
Constraints.mustPayToPubKey requires txSignedBy?
For a contract, I want to use Constraints.mustPayToPubKey for an arbitrary pubKeyHash (pkh), such as a lucky winner in a lottery.
Question: Does the validator need to check that the transaction sees that pkh (using txSignedBy or similar)?  If so, why?

Does the validator need to check that the transaction sees that pkh?

Yes. There is more than one way to organize the logic though.
Whichever way you structure the lottery, I will assume that the winnings are owned by the script. Any transaction that spends UTxOs owned by the script need to meet the qualifications of the validator.
As you say, one way to construct the smart contract would be to make sure you mustPayToPubkey of the winner. The validator would then need to guarantee that the output of the "pay out winnings" transaction includes the winnings and they are going to the winner's pkh. This wouldn't use txSignedBy, but rather do some combination of checks to guarantee the winnings are going to the correct pkh.
The way I would suggest modelling it is by saying only the winner can claim the winnings. In that case you could use txSignedBy.
This approach is similar to how the vesting example works in the PPP. It doesn't use txSignedBy, but rather just checks that the beneficiary is among the signers, essentially doing the same thing.
You don't even need to specify mustPayToPubKey at that point because it will default to the transaction builder's wallet. See the vesting example's grab constraints.

But what would happen if the tran does not see the pkh? Why can he not get paid in that case?

I'm not sure what you mean by "tran does not see the pkh." Do you mean if the validator doesn't see the pkh as a signer of the transaction?

Yes. Why is that a strict requirement?

Isn't that the behavior you want? You only want the winner to be able to spend the lottery winnings? When you spend ADA from your own wallet, the transaction is only valid if the owner of the ADA signed the transaction. This is the same as that, but the winnings are at the script address, rather than your own wallet, so you need write those requirements into the validator.

If you didn't have that requirement, anyone could spend the winnings.

I guess I don't understand what forces the winner to be hooked up to the transaction in the first place -- is that perhaps one of the purposes of the constraints when submitting the transaction?

More questions: So there seems to be two approaches, either focused on the current owner who mustPayToPubkey or as you recommended , focused on the winner who mustSpendScriptOutput . First why is your approach preferred -- simply because the use-case uses it? Second, is it wrong to use both approaches together? And third, why are both approaches allowed, being that it (apparently) only serves to complicate  the matter?

You might be thinking about what smart contracts do slightly wrong. I pointed out in your other question here: https://cardano.stackexchange.com/a/2315/1130. Scripts on chain are completely passive. In the case of a lottery, I'm imagining after a series of events, there is a pot of money that has been won by some pkh. We want that pkh to have access to the money. We have two options: Allow anyone to submit a transaction to send those funds to the winner pkh, OR allow the pkh to spend the money however she chooses. Since only the winner is motivated to submit a tx, I went with that approach.

Scripts take of space on the chain and cost gas to execute. Simple is better. Not to mention safer. And, as I mentioned. Only the winner is motivated to submit a tx to claim the funds, there is no need to provide multiple ways to access the money. Both approaches are allowed because there are infinite different smart contracts people might want to write. It's easy to imagine a script that would require you to send funds to some wallet. Maybe a tip to the contract writer or something :P

I see, so according to your approach, the winner would be notified externally (e.g., email), and thereby be instructed to open their wallet in order to request request the winnings -- such that if they fail to do so, they forfeit?

I also do not understand what you wrote above Allow anyone to submit a transaction to send those funds to the winner pkh. This obviously would not just be anyone but rather only one entity: The owner of the lottery who actually has the funds to disburse!

I imagine that the funds are on the script, and no-one owns them. That's the point of a decentralized smart contract after all. If there is some central owner of the funds, there would be no need for a smart contract on-chain, you could just have an agreement off-chain.

Thanks for clarifying that last point.  Kindly advise regarding your approach that the winner would in fact need to proactively submit tran in order to claim.

Yes. Since the script is passive, the winner wouldn't get paid unless they proactively submit a "claim" transaction of some sort. This of course could be automated off-chain, either to notify the winner or possibly have the wallet submit the "claim" transaction automatically.

FYI the SimpleEscrow plutus use-case uses mustPayToPubKey

That's a perfect example of a transaction that needs to send outputs to different parties. Notice in the validator https://github.com/input-output-hk/plutus/blob/1f9569aec76e2a4c641a16807d5a157c07db69c9/plutus-use-cases/src/Plutus/Contracts/SimpleEscrow.hs#L113
it only checks that the payee was paid. The line you linked isn't technically necessary, it's just explicitly saying you want the rest of the money. You could send it anywhere and the validator would still pass, as long as the payee gets their due. You would probably never do that, but it's a good example of how validators stay simple.

I do not understand your assertion that mustPayToPubKey is superfluous (isn't technically necessary).  Where else in the redeemEp contract do you see instructions for sending money to target, or only allowing target to claim?

redeemEp is off-chain code for building a transaction. There is nothing preventing me from writing different off-chain code that builds a different transaction as long as it satisfies the same on-chain validator (validate). The validator doesn't mention anything to do with the our public key, only the payee's key. So for a transaction to be valid, the constraint Constraints.mustPayToPubKey (Ledger.pubKeyHash pk) value isn't necessary.

Question: From where did you gain your expertise in Plutus? Is there some book you can recommend?

I'm far far far from an expert. Unfortunately there isn't a book yet. I've been through the Plutus Pioneer Program, I've written my own SC (which took me a while), and I try to answer people's questions here. We're all figuring this out together since Plutus is so new. Trying to get as much exposure as possible.

There actually is a downside to the mustPayToPubKey  approach, in that that the tran is subject to sabotage unless geq is used in the validator, as is explained here


text:
Disable contract after purpose achieved
After a contract has fulfilled its mission in life (such as pay beneficiary), is it proper to delete or disable said contract? If so, how exactly is this done?
Offhand, I would think that if the contract gets needlessly validated (for the rest of eternity [yikes!]) it would needlessly clog up the system.

I don't think "disabling" a contract is possible since a "contract" in Cardano is not deployed anywhere on chain. The script/contract is supplied with a transaction that wants to spend UTXOs sitting at the contract address (which is basically a hash of the script code). Anybody can construct such at transaction at any time and the validator node will need to validate it.
The network will not be congested because as others have pointed out "contracts" in Cardano are completely passive and do not run on their own. They only run if a transaction wants to spend UTXOs sitting at the script address. If somebody would want to attack the network and construct millions of such transactions to run the code it would ruin him because each transaction has to pay fees and the fees are based on the resources needed to run the script. The more computational/memory heavy the script is the more fees you have to pay.

I would think that if the contract gets needlessly validated (for the rest of eternity [yikes!])

Ah. This is a misunderstanding. Scripts are completely passive. Nothing gets run unless a transaction interacts with it.
So, in the case of a contract that pays a beneficiary, the script doesn't do that for you, it includes a validator that says "yes" or "no" to anyone trying to spend the UTxOs at the script address.

Ok, so allow me to rephrase: Is it correct that if all the constraints of the submitted tran end up being satisfied, then the tran stops being validated?

"constraints of the submitted tran end up being satisfied." You can build a transaction that satisfies whatever constraints you give it, but you can only interact with scripts with transactions that meet the constraints of scripts' validators. "then the tran stops being validated?" Do you mean the transaction is invalid? Any transaction that meets the constraints of the script's validator can spend UTxOs (either to take them or to update the state) from the script address. In perpetuity. That being said, there would be no reason to interact with a script that doesn't have anything to spend.


text:
Are Validators pretending transaction already completed?
A validator is called prior to transaction's start (not to mention completion). But yet a validator routinely checks if a potential recipient has already received his funds, and other such tests about events in the past.
So is the validator pretending that the transaction has already completed, whereas in truth the transaction has not yet started -- and perhaps never will?

Yes, a validator is called prior to the start of the transaction as it part of the constraints that determines if the transaction can proceed. A validator that executes on-chain has no visibility of past transactions. It can only see the transaction it belongs to, its inputs and input data supplied to the validator.
It is the off-chain code that constructs the transaction that has visibility of the full blockchain of past transactions.


text:
How to move Cardano Node stake pool to new IP address?
We are changing hosting services, and want to move the BP and Relay nodes to new machines.  They are all set up and synced with Mainnet, but when we re-run the 05c SPOS script it complains there are no funds on the wallet address.  We shouldn't have to pay the registration fee again.  All we want to do is update the IP addresses of the Relay Nodes on the network.  All of the keys are moved over to the new servers, and the topology file is updated.
We did some searches and found some articles, but nothing that was helpful.
The command we ran is from the keys folder:
05c_regStakepoolCert.sh myPool myWallet REREG
It says:
No funds on the Source Address!

You don't have to pay the 500 ADA registration fee, but you do have to pay the regular transaction fee since updating a pool registration must be submitted via a regular transaction.
If all you are doing in this transaction is submitting a pool cert, it should cost you somewhere around 200,000 Lovelaces (0.2 ADA). Just make sure the new pool cert has the new IP addresses.
Pro tip: if you purchase a domain name (say, mypool-rocks.com), you can actually avoid having to resubmit pool certs every time you change IPs. Instead, you can point your pool certs at a DNS address (i.e. relay1.mypool-rocks.com and relay2.mypool-rocks.com), and use a DNS resolver like Google to point your IPs at those respective sub-domains. This works great for moving IPs around, just make sure that your security is tight with whatever DNS resolver you choose.

Aha, that makes sense.  FYI, I added 1A to my wallet, and that was insufficient.  It then proceeded to list the amount needed, which adds up to 1196433 Lovelaces:  196433 for TxIn/TxOut, 196433 for re-registration, and 803567 for being returned to payment address...  Makes sense we have to have funds to pay the tx fee.

I don't think the second 196433 fee is for re-registration. As far as I am aware there is no "re-registration" fee. However, there is a minimum UTXO value of 1 ADA (meaning every UTXO on Cardano must have at least 1 ADA or 1000000 Lovelaces in it - which is exactly what should be sent back to you as change.

I will say I had 1A in the wallet and it said not enough funds, but when I had 2A it worked.  Thanks again!


text:
How to obtain wallet addresses of stake pool delegators?
I am trying to figure out how to write some scripts that will dish out rewards to delegators on my staking pool - I want to get the wallet addresses of delegators, and determine rewards based on the relative amount they have staked (e.g. 5%, 10%, 50%...).  Has anyone done this?  If so, how?  Here is what I tried:

cardano-cli - I tried digging through cardano-cli queries, but I didn't see any relevant queries to what I am trying to do.
blockfrost - using /pools/{pool-id}/delegators, I can get a list of delegators and the amounts they delegated, but these are staking addresses, and I can't do anything with these addresses directly.  I can easily calculate relative stake with this based on live_stake value returned.  So, I tried /accounts/{stake-address}/addresses with the first delegator stake address, and it returns something like 15 addresses.  What do I do with that?  How do I know which is the wallet address I want to send rewards to?

You were onto the right idea, try the blackfrost approach again. After calling /accounts/{stake-address}/addresses endpoint you will see a list of addresses linked to the stake address. Pick any address from that list.
Another approach that should work is using cardano-address. First get all stake addresses:
cardano-address address inspect [ADDRESS]
Then query your cardano-db-sync. Use an INNER JOIN query to map addresses to stake addresses.

Aha, lightbulbs are turning on.  That is cool, thanks for sharing that.  One more depth to delve into.  I think the blockfrost may be more straightforward and simpler, but I will keep that in mind.

What I do is query & grab all the data I need from:
https://cardanoscan.io/pool/f8e64037e3917cd7cb94969a5374e11b9e6c939b4b69118a8eb4509f?tab=delegators
And then send whatever I want using cardano-cli. Works like a charm!

Hmm, this is the same as the blockfrost /pools/poolid/delegators call.  It is returning staking addresses.  But you say you send money to those addresses no problem?

I've never heard of or used blockfrost, but yes - you can send money to those addresses in Cardanoscan no problem. I do it everyday and have never enountered an issue.

You should check out Blockfrost.io - it's a free RESTful API to call Cardano networks (mainnet or testnet)

How do I know which is the wallet address I want to send rewards to?

In theory, any address associated with the staking key will do.
Just a reminder that the address can be mangled, so the owner of the stake rights might not be the same person as the owner of the payment funds.

I'm not sure the implications of this statement.  Does this mean that the address that is returned may not be the address of the staker?  That seems at odds to the call, so I don't think that's what you meant.  Or what payment funds are you talking about, you mean the funds in the wallet that is staked to my pool?  Sorry, I am new to SPO, so I am trying to make sure I understand the answers you are giving.  Thanks for replying!

You pick any of the addresses associated with the staking address from the point 2, they are all in the same wallet.

What do you mean "from the point 2"?  Do you mean anything other than the first address?

This is point 2:
blockfrost - using /pools/{pool-id}/delegators, I can get a list of delegators and the amounts they delegated, but these are staking addresses, and I can't do anything with these addresses directly. I can easily calculate relative stake with this based on live_stake value returned. So, I tried /accounts/{stake-address}/addresses with the first delegator stake address, and it returns something like 15 addresses. What do I do with that? How do I know which is the wallet address I want to send rewards to?

Any of those 15 address will be OK. They are all in the same wallet.

You can get the wallet address of stake pool operator by using adapools.org. First go the desire pool, then delegators and click on the pool staking address. You will see it. An example can be found here.

This does not answer the question. The OP was asking for delegators addresses, not the SPO's address.


text:
How to move Stake Pool Node to new IP address?
I believe we are missing something.  Earlier I asked a question on how to reregister the stake pool from the new hosts.  However, apparently I had not asked the entire question - which is, how do you go about moving the node?  As in, what are the steps?  The documentation on this has been pretty hard to find.  What I did was to set up the node on the new hosts, transfer the keys, and then re-register the stake pool using the SPOS scripts.  But, the IP addresses of the relays aren't being updated on the net - so how do I update the topology file?  I found a Topology Updater script, but I can't just download and run it - it appears that a set of very specific prerequisites needs to be set up, and I don't see where that is documented.  So how exactly do I take my updated topology file and submit it to the network to supersede the old one?

In general, there's nothing in the protocol itself that cares where your node made blocks, but here's some best practices on what you would do:

Create your new relays in the new hosting center
Setup bi-directional connections between your old/new relays in your topology files
Notify any pools you're pairing with of your new relays so they can add them to their topology files as well
Re-register the new relays for your pool so IOHK and other pools getting information from db-sync to generate their topology files can find your relays
Sync a new "relay" against your new relays in your new hosting center. This will eventually become your block producing node
Identify a time when your node will not produce a block that's a good maintenance window (ideally a few hours in case anything goes wrong)
cleanly stop both the old block producing node and the new one (that's currently a relay) with a SIGINT signal so the database is cleanly shutdown.
(optional but good practice) generate a new KES key an opcert
restart your new block producing node with the VRF skey and new KES/opcert.
Ensure your relays have adequate incoming relay connections from outside prior to shutting down your old relays.
remove old relays from your new relay topology and restart them

This to me sounds like a good, comprehensive set of steps.  Forgive my ignorance as a first-time SPO, maybe I could confirm details of some of the steps.  2) Bi-directional connections meaning what, I add each of the old/new relays in each of the relay topology files?  4) Re-register, meaning run SPOS 05c script?  Or is there a specific cardano-cli command or such?  10) Adequate relay conxs - how do I do this, is this a cardano-cli query?

i think you are missing something and you make more complicated your question.
every pool needs only one BP (second one for redudancy, but never run 2 BPs at the same time) and you also need Relays, more than 2 for the redudancy.
the BP (block producer) need his settings and only connections to your relays. no other connection to any other Relay in the network. that is for your security. this node, the BP, need 3 files so that runs as BP. that is the only different to the Relays.
which means now,
the IPs which are known and used in public, are the IPs from your relays.
now to your point.
if you want to install new node, what ever it is (either BP or Relay), you need a normal installation as it was for any other old Node.
if you want to use this new Node a Relay,

prepare it as relay,
connect it with your BP only
register the pool with your new public IPs

if you notice here, in importan key_step is to register again the pool with your new IPs (from Relays)
in case now you want new installation for your BP,
then please just install new node, connect it with your Relays, and add the proper files to run as BP.
please let me know, if that is what you exactly want to make it clear.
for any further support, let us know and we are happy to assist you.
TTS17

thank you so much for your answer!  I want to make sure I understand.  When you say "register the pool with your new public IPs" I ran the SPOS registration script 05c to register the stake pool with REREG as a command line parameter, from one of the new nodes.  I believe this submitted the topology file with the new IP addresses, right?  Or, maybe more to the point - how do I update the Cardano network topology file with my new relay IP addresses?

do you use cntools? - here is a great guidance from cool operator -
https://forum.cardano.org/t/how-to-set-up-a-pool-in-a-few-minutes-and-register-using-cntools/48767/1699   -  i speak for the "STEP 8 - register the pool" -/- in your case you have to go  >> POOL >> MODIFY

to update the topology file, you need a script to run everyone ,which s called "topologyUpdater"

OK I will have a look.  I didn't download cntools, and like I said in my post, I tried the topologyUpdater.sh, but it didn't work, and I had to run the prereqs.sh, but that asked for an empty folder, so I didn't understand what it was going to do.

OK,  now it goes to be more complicated, as we open more tickets,
if you need further support, find telegram group : https://t.me/CardanoStakePoolWorkgroup - or open tickets in : https://forum.cardano.org/ -
we are huge community and happy to support you.
welcome mate

I did get topology updater to work, I found the env settings. But I dont see the new relays in https://explorer.mainnet.cardano.org/relays/topology.json  I can try Telegram, I figured StackExchange is the best method of capturing the Q&A.

if you installed properly the node, and is synched, did you modify the pool with the new public IPs of your Relays?

Yes, the new node is synced, all 3 servers up to date.  What exactly do you mean by "modify the pool with the new public IPs of your Relays"?  The mainnet-topology.json files on all the new pool node servers have the new IP addresses, and the cron job of topologyUpdater.sh should have submitted those, right?  I noticed that a week later, adapools.org still has the old relay IPs.

do you build your whole installation with cntools or manually? or another installation guide?

you have to Register the stakepool certificate but without "Generating your delegation certifcate", means you dont have to pay again the 500ADA -----i have 2 different ways, -CNTOOLs -> >> POOL >> MODIFY >>OnLine or OffLine -> then you select your Pool and give values to all parameters again, but using your new Relays IPs.  ///// the second way is the manual by commands, how it was in the past 1. Generating the stakepool certificate(cardano-cli shelley stake-pool registration-certificate) 2. Calculating the fees, 3. building the transaction, and 4.submitting it

if some / a comment / answer is useful, you can give a credit :)

Yes, absolutely I will.  Our stake pool is still not operational, and I have had some personal challenges stopping me from working on it at the moment.  I apologize for the delay.  I followed the stakepool247 guide to install, so I installed via their script, not via cntools.  This is the third stakepool I have installed, but I have never moved one before.  I am considering deregistering, get the 500 ada back, and re-registering from the new pool.  The registration I ran using SPOS scripts, and I did that from the BP.

Another idea might be to wipe the OS back to plain Ubuntu, and do a CNTOOLS install.  I have never done that before, but it can't be that much different.

if you want, find me in telegram or other chats and groups, i can help you,,
there is also amazing forum.cardano.org/
anyway, i am really happy to assist you. find me
tts17.com, or twitter : tts1710

cntools is what i use and recommend it.

it is so easy, and i can assists 101%, the point is , you need the learn and understand the folder structure.

First thing: you can re-register the stake pool from any host in the world. You don't have to do it from one of the stake pool nodes.
Second thing: the only keys you need on the block producer node are: kes.skey, vrf.skey and the operational certificate (node.cert or oper.cert, depending on what guide you were using). It is not advised to have the payment keys on a server connected to the Internet. Maybe it is a requirement for the scripts you are using, but I would not do that.
If the new relays are in sync, you should install the topology updater script. You have some requirements to install, but you can use the documentation.
https://cardano-community.github.io/guild-operators/basics/#pre-requisites
Once you are running the topology updated script on the new relays and you have incoming connections, you can re-register the stake pool with the new relays. I assume you already have the new block producer connected to the new relays (both directions connections between relays and block producer). But you should not run both block producers in the same time, if you have blocks scheduled. You can also connect the new block producer to both old relays and new relays, and stop the old block producer even before updating the stake pool registration certification.

When I run the prereqs, don't forget I have an already-installed, running node.  I enter the path to the install folder, and it says I have to give it an empty path.  I don't know what it is going to do, and the documentation isn't clear on my question.  Do I create an empty folder and run the script to that?

I think the prereqs.sh will only install some packages that you need to run the scripts. You may already have them. You can try to run topology updater without running the prereqs.sh, but if it is not working correctly, take a look to the script to see what it is doing and maybe you can see what's missing. I know for sure I have issues with gLiveView.sh for example because I did not have jq and bc packages installed.

I definitely have jq, not sure about bc - jq is used by SPOS... I also had issues with gLiveView hanging the node, back on 1.29.0 when I got started with cnode.  I think I will try the topologyUpdater script, run the prereqs to an empty folder and see what happens.  Take a snapshot of the host first.

OK, I configured and ran the topologyUpdate script, set it up to run every hour.  However, when I looked at the Cardano centralized topology file (https://explorer.mainnet.cardano.org/relays/topology.json), our relays are not there after 24 hours.  How do we get our relays on that list?


text:
How to get the funds available at a script using Plutus?
I am currently working on Lecture 8 in the Plutus Pioneer program.
I want to view funds available at a script address.
There appears to be a function that makes this easy in Ledger.AddressMap
-- | Get the funds available at a particular address.
fundsAt :: Address -> Lens' AddressMap UtxoMap
fundsAt addr = at addr . non mempty

However, I have not been able to get this to work.
When I try this
fundsAt scriptAddress

I get the following error
Ambiguous type variable ‘f0’ arising from a use of ‘fundsAt’
  prevents the constraint ‘(Prelude.Functor f0)’ from being solved.

My attempts at trying to make the type unambiguous have not worked, and I am struggling to understand Lens'.
Does anyone know how to get the fundsAt function to work?

If you are trying to do this in your offchain code, I would suggest using Plutus.Contract.utxoAt instead.
Here is an example of it being used in the gift code.

I did see that example, but is there a reason why that's a better approach? It seems like fundsAt is a clearer and more direct way to get the data I want and I'm just struggling with the Lens' type.

They both give you a UtxoMap. Notice that the return type of the grab function is the Contract monad, just like utxoAt. It's what's meant to be used in the off-chain transaction-building code. I doubt there is a conversion between Lens' and Contract.


text:
How can I find the IPFS URL for a CNFT.io asset?
I've tried several ways but couldn't find a relyable way to find the IPFS url for a CNFT.io asset.
I tried to find the policy id in https://pool.pm/tokens and in https://cardanoscan.io/. In the latter one I can find the policy id but not the right asset / token and even when I find it by manually searching for it, then I don't find the metadata for it that contains the IPFS URL. Is there a relyable way to find it?

Not sure if this is what you want to know.
For every asset on CNFT.io, there are three dots at the top right side.

Click on Cardanoscan option
It'll open cardanoscan with your token, i.e. https://cardanoscan.io/token/dcb16550b3831a9c675b5bd827ad0ffced2dc0310b0d839c5c1dcd5e.CuteDudes3472
Go to Mint Transactions tab and click on the transaction.
It'll open the transaction in cardanoscan, i.e. https://cardanoscan.io/transaction/35c1c8fb3da4a6a23476b2d05288ae2314468b92e4fb6c87e8801590689f85e7?tab=tokenmint
Go to Metadata tab and click on label 721
There should be displayed the metadata of the NFT, including URL to the image or files.

"For every asset on CNFT.io, there are three dots at the top right side...".
Argh. That was the simple solution that I missed :facepalm:
I tried to find it using the policy id and the asset id. Thanks a lot!


text:
Do Cardano NFTs contain stable content?
In our company we discuss the Twitter post of the Signal founder: https://moxie.org/2022/01/07/web3-first-impressions.html. One critique is, that the NFTs don't contain the hash of data (jpg, ...) but a link to a centralized page that is outside of the control of the blockchain and whose content can change.
How does it work for Cardano or CNFT.io for example. Do they contain the hash of the image or a Link to IPFS or something?
When I look at an NFT on CNFT.io I don't find a hash that works with https://explorer.cardano.org/ to check it myself.
Thanks in advance for hints!

Ah, using https://cardanoscan.io/ with the "POLICY ID" of a token on cnft.io I can find the token on the chain. E.g. https://cardanoscan.io/token/8c06b3c611ec9bc9037c76a9e2cf270c7a147341e6daffeda614cdd5426f726733323838. So that part is answered.

I believe the metadata in a Cardano NFT is not set in stone. As in you can decide what it contains. Using a reference to an ipfs storage location is one convenient way to add the actual content of the NFT.
You can read more about the technical process of minting NFT's here:
https://developers.cardano.org/docs/native-tokens/minting-nfts/
There's also an interesting discussion on having a metadata standard going on in this CIP (Cardano improvement proposal):
https://github.com/cardano-foundation/CIPs/pull/85
If you want to see the metadata of a specific NFT you should be able to see it on the marketplace you're using. Personally I've found https://pool.pm/tokens very useful for finding tokens and their metadata.

Thanks a lot. Seeing the NFTs at https://pool.pm/tokens and their metadata with the IPFS link was very useful!