I'm trying to locate the public keys associated with a Bitcoin block's transaction inputs and outputs.
Can anyone tell me where those are encoded?
Thank you.
Simply put, in general you can't.
Depending on the signature schema, all you could get would be a hash of that public key, or, even worse, a hash of a redeem script.
More specifically, you could get some public keys in some cases.
This is a partial list of what you could get:
Pay-to-pubkey-hash scripts (P2PKH): you get the public key from the scriptSig for the input BTC address
Pay-to-pubkey (P2PK): you get the public key from scriptPubKey for the output BTC address
Pay-to-script-hash scripts (P2SH): you get the public keys from the scriptSig for the input BTC address
There are other signature schemes and in standard transactions you should be able to get either the source public key or the destination public key.
What you could do is indexing the whole blockchain and fill the gaps in transactions where BTC addresses are not included together with their public key. But, for instance, if your BTC address appears only in P2PKH outputs, you have no means to find that public key.
Related
What I would like to achieve:
Assuming I have 500 JSON files already uploaded to IPFS, each one represents a meta data of an NFT.
Every time a user triggers mintBatch(number) function, I wish a number of NFTs would be minted randomly for this user, and the NFTs that have already been minted should not be minted again.
Hence, I think I will need a place to store the IDs of the NFTs that have been minted, so that the future randomize function can avoid those IDs when minting.
I am thinking if I should do this on-chain or off-chain. If off-chain, things can be a lot easier as I just need to upload the number randomly generated off-chain and record them in my off-chain database. But some articles say it would be costly and low efficient (which I don't quite understand the reason). On the other hand, on-chain was described on some other articles that has less security as users can see the randomize mechanic on blockchain and try to hack it, but some other articles say it is more efficient and will genenrate less gas.
Normally which way would people choose, and normally how do they do it?
UPDATE: To prevent users from minting the same json that others have minted, I am thinking of putting json CIDs in an array, and removing the minted item from it once a mint function is called. I wonder if this would change the suitable way for minting randomly.
Check this question:
How to generate a random number in solidity?
Only true number generation is only possible with using RNG services like chainlink.
After get the random number from chainlink, you can pick one of your json files and give it to user.
Background: Suppose I want to verify the ownership of some tweet or some picture by looking up the data in the blockchain. If my understanding is correct, I need to be able to assign a unique tokenId that represents that tweet/picture.
Question 1: Is there some standardization on how this ID is assigned? Do different platform perform this mapping in a unique way? I feel like without such a standardization, the non-fungibility becomes questionable (e.g., do you really own this tweet, or do you only own it if you apply the tweet->token ID mapping you crafted yourself?).
Question 2: Could you provide a few examples of how exactly is the token ID assigned to some (well-known) NFTs?
Is there some standardization on how this ID is assigned?
The ERC-721 standard explicitly states that there is no standard to assign the ID (except for the uint256 datatype):
While some ERC-721 smart contracts may find it convenient to start with ID 0 and simply increment by one for each new NFT, callers SHALL NOT assume that ID numbers have any specific pattern to them, and MUST treat the ID as a “black box”.
e.g., do you really own this tweet, or do you only own it if you apply the tweet->token ID mapping
Token ownership does not mean that you own the underlying resource. It only means that you own the token (representing the resource).
Could you provide a few examples of how exactly is the token ID assigned to some (well-known) NFTs?
CryptoKitties - link, line 412, incrementing
uint256 newKittenId = kitties.push(_kitty) - 1;
CryptoPunks - link, lines 73 and 83, assigning ID set by the (authorized) caller
mapping (uint => address) public punkIndexToAddress;
function setInitialOwner(address to, uint punkIndex) {
// ...
punkIndexToAddress[punkIndex] = to;
When an NFT is minted with a smart contract, associated with the NFT TokenID, the block chain also typically records a URI (universal resource identifier) that points to the NFT metadata (usually a json file). This URI can be obtained by querying the blockchain via the smart contract address and TokenID. The json file itself includes, among other things, another URI that points to the digital asset linked with the NFT. If immutable URIs are used (e.g. IPFS URIs), the URI recorded in the block chain for the NFT TokenID is unambiguously linked to the unchangeable json file which unambiguously links to the unchangeable digital asset. As Petr correctly points out, technologically, nothing prevents anyone else from minting another NFT that also records the same URI and therefore points to the same json file (and by transitivity to the same digital asset). I've tried to be precise in the preceding statements to avoid incorrect extrapolatory claims that would actually depend on the smart contract implementation details.
I am new to Blockchain, learning to implement it in javascript while understanding things. I have one question that I tried to search a lot, didn't get any clear explanation.
Question : Lets suppose I have 3 transaction records and previous block hash. I also found out the Nonce value. Combined I got desired hash of 4 '0's at front. Now everywhere I read, it says this proves the validity of block. But How?! I mean, What if before finding hash, I (or someone) TAMPER WITH THOSE 3 TRANSACTIONS. I could again find a hash with 4 '0's but this time I altered AMOUNT in those 3 transactions (making them faulty).
How can we be sure that those transaction amounts are LEGIT. Consider this is the newest block, I am concerned about validity of those 3 transaction records.
If proof of work doesn't guarantees the critical information (transaction records) then what is the point of it. What thing validates those transaction records in block are not faulty? (The miners haven't tampered with them, before adding block to blockchain)
The proof of work & hash block functions in JS :
// Hashing Single Block
Blockchain.prototype.hashBlock = function(previousBlockHash, currentBlockData, nonce){
const dataAsString = previousBlockHash +
nonce.toString() +
JSON.stringify(currentBlockData);
const hash = sha256(dataAsString);
return hash;
};
// Proof of Work
Blockchain.prototype.proofOfWork = function(previousBlockHash, currentBlockData){
let nonce = 0;
let hash = this.hashBlock(previousBlockHash, currentBlockData, nonce);
while(hash.substr(0, 4) !== '0000'){
nonce++;
hash = this.hashBlock(previousBlockHash, currentBlockData, nonce);
// console.log(hash);
}
return nonce;
};
I'm going to try to give a simplified answer, as there are many details that are not required to understand the solution.
First of all, let's look at what a transaction consists of:
The transaction data:
the address the money comes from
the address the money is going to
the amount
a signature of the transaction data created with your private key
your public key
When you create an address for people to transfer money to, where is this address coming from? First of all, you create a public/private key pair. A public/private key pair is the result of some complicated mathematics. What you can do with these keys is interesting. You can sign a message with your private key. If your friend has your public key, they can verify that the signature is valid for that message, which means that they can verify that it was you writing that message.
In blockchain, an address is the sha256 hash of a public key.
Now when it is time to transfer your money, you need to do two things:
Show that you are the owner of that address. You do that by providing the public key. The miners in this case can hash your public key to verify that it results in the 'from' address.
Confirm that you own the private key. You do that by creating the signature of the transaction data.
If a miner changes the 'to' address, the 'from' address, or the amount, the signature of the transaction data isn't valid anymore.
If a miner decides to add a new signature based on the changed data, it won't verify anymore with the public key in the transaction.
If the miner decides to change both the signature and the public so they match, then the 'from' address won't be correct anymore as it is the hash of the public key.
I left out some details like:
A 'from' address refers to a previous transaction
The amount in the previous transaction needs to be spend completely. So if there is too much in there, you will have a second 'to' address which is in your control, basically transferring the rest back to yourself
There can be many 'from' addresses and 'to' addresses in one transaction. Each 'from' address requires a public key and signature.
The transaction actually contains a script that says how to verify the addresses and signatures. If you expand the language used in that script, then you are talking about a smart contract.
There are private keys which can generate multiple public keys, and therefore multiple address, so you don't have to manage multiple private keys.
There is no way to verify if a 'to' address is valid. So you can transfer money to an address where nobody has the private key for.
You can find the complicated details of what goes into a transaction here: https://en.bitcoin.it/wiki/Transaction
The transaction record itself is digitally signed by the party which created the transaction in the first place. Only he/she has the private key to generate the transaction. When you change one value in the transaction record, the digital signature becomes invalid and therefore the transaction itself becomes invalid. You can change the transaction record data, but then no other node will accept this transaction (or the mined block) as it contains invalid data.
This check if a transaction record itself is valid or not is unrelated to the proof of work you have to do to mine a new block.
Is it possible to get DynamoDB to automatically generate unique IDs when adding new items to a table?
I noticed the Java API mentions #DynamoDBAutoGeneratedKey so I'm assuming there's a way to get this working with PHP as well.
If so, does the application code generate these IDs or is it done on the DynamoDB side?
Good question - while conceptually possible, this seems not currently available as a DynamoDB API level feature, insofar neither CreateTable nor PutItem refer to such a functionality.
The #DynamoDBAutoGeneratedKey notation you have noticed is a Java annotation, i.e. syntactic sugar offered by the Java SDK indeed:
An annotation, in the Java computer programming language, is a special
form of syntactic metadata that can be added to Java source code.
As such #DynamoDBAutoGeneratedKey is one of the Amazon DynamoDB Annotations offered as part of the Object Persistence Model within the Java SDK's high-level API (see Using the Object Persistence Model with Amazon DynamoDB):
Marks a hash key or range key property as being auto-generated. The
Object Persistence Model will generate a random UUID when saving these
attributes. Only String properties can be marked as auto-generated
keys.
While working with dynamodb in javascript with nodejs. I use the npm module uuid to genrate unique key.
Ex:
id=uuid.v1();
refer :uuid npm
By using schema based AWS dynamodb data mapper library in Node.js, Hash key (id) will be generated automatically. Auto generated ids are based on uuid v4.
For more details, have a look on following aws package.
Data Mapper with annotation
Data Mapper package for Javascript
Sample snipet
#table('my_table')
class MyDomainClass {
#autoGeneratedHashKey()
id: string;
#rangeKey({defaultProvider: () => new Date()})
createdAt: Date;
}
The client can create a (for all intents and purposes) unique ID either by picking a long random id (DynamoDB supports 128-bit integers, for example), or by picking an ID which contains the client's IP address, CPU number, and current time - or something along these lines.
The UUID standard even includes a standard way to do this (and you have libraries in various languages to create such UUIDs on the client side), but you don't really need to use a standard.
And interesting question is how do you plan to find these items if they have random keys. Or are you planning to use a secondary index?
The 2022 answer is here:
https://dev.to/prabusah_53/aws-lambda-in-built-uuid-382f
External libraries are no longer needed.
Here is another good method taken from mkyong
http://www.mkyong.com/java/how-to-get-current-timestamps-in-java/
I adjusted his method to get the milliseconds instead of the actual date
java.util.Date date= new java.util.Date();
System.out.println(new Timestamp(date.getTime()).getTime());
The approach I'm taking is to use the current timestamp for the hash-key (or the range-key, if using a range-key too). Store the timestamp as an integer, representing the number of milliseconds since the start of the "UNIX epoch" (in the UTC timezone). Many date/time libraries can produce this number for you.
This has the advantage that if you want to have a "creation time" field in your table, your UUID already stores this information. Just call another method in your date/time library to convert the timestamp to a readable format.
(Be sure to handle the exception which will occur if a second item is created in the same table with the same millisecond timestamp; just fall back and retry the operation in that case, with a slightly later, current timestamp.)
For example:
User table
hash-key only: userID (timestamp of the creation of this user).
WidgetAttributes table
hash-key plus range-key.
hash-key: userID (use the userID from the User table of the user to whom the widget belongs).
range-key: attribID (use the timestamp of the creation of this widget-attribute).
Now you can run "query" operations on the WidgetAttributes table to get all widget-attributes for a certain user; by using "greater-than-zero" as the query-parameter for the range-key.
What kind of technique does use Google Plus to generate users' unique ids?
Example
https://plus.google.com/102766325060234825733/posts
You can only assume that they are randomly generated ID's that are large enough to be generated non-sequentially with sufficient entropy.
The ID's are too big to be stored in a bigint field which is interesting, again probably due to the required entropy and non-sequential requirement (so that nothing can be inferred by comparing userid's).
A simple encryption of a serially generated number, with a secret key can be used to generate the IDs. It can be a 1 way hash, or a decryptable encryption.
The reason for not using serial numbers directly is obvious: You can easily guess userids of other users on the network, which can result in Bots scraping the content of the network.