Send a NFT together with Tokens - token

Is there a way to send an 1155 or 731 nft in one transaction together with a token(erc-20)
and if yes could someone provide an example

You can create a muticall contract that wraps both token transfers into one transaction.
Example:
pragma solidity ^0.8;
import "#openzeppelin/contracts/token/ERC20/IERC20.sol";
import "#openzeppelin/contracts/token/ERC721/IERC721.sol";
contract MyContract {
IERC20 erc20Token = IERC20(address(0x123));
IERC721 nftCollection = IERC721(address(0x456));
function sendFromThisContract(address to, uint256 erc20Amount, uint256 nftId) external {
erc20Token.transfer(to, erc20Amount);
nftCollection.transferFrom(address(this), to, nftId);
}
function sendFromUser(address to, uint256 erc20Amount, uint256 nftId) external {
erc20Token.transferFrom(msg.sender, to, erc20Amount);
nftCollection.transferFrom(msg.sender, to, nftId);
}
}
In case of sendFromUser(), the user needs to send additional 2 transactions to be able to perform this action:
to the ERC20 token contract, approving MyContract to operate the user's tokens
to the NFT collection contract, approving MyContract to operate the user's specific token ID (or all tokens)
It is not technically possible to transfer multiple tokens (with different contract addresses) in one transaction without an intermediary or without the approvals. This is because when you're sending a token, you're sending a transaction to the token/collection contract. And by design, a transaction can have only one recipient.

Related

How to get the amount of token sent to a smart contract via the fallback function in solidity

Let's say I have a token A and a smart contract B.
A user sent some amount of A to to the contract B by direct transfer through his wallet.
In the fallback function of the smart contract B, how will I get the amount of token A that was sent?
msg.value did'nt give me anything since it's not Eth that was sent.
When your contract receives ERC-20 tokens, the fallback() function is not invoked - nor any other function. Meaning, your contract does not get notified about incoming ERC-20 transfers unless you pull them with transferFrom().
contract YourContract {
function pullTokens() external {
// need to have prior approval
tokenContract.transferFrom(msg.sender, address(this), amount);
}
}
Note: Some other fungible token standards define these notification functions for recipient contracts - for example ERC-777 and its function tokensReceived().

How to add tokenomics to a ERC20 token?

I have taken different courses and even tho they explain how to make a token I haven't been able to learn how to implement tokenomics.
For example fees for transactions, burning to LP etc...
I leave a link to the openzeppelin standard
Would be great to have some more detailed examples on it.
https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/ERC20.sol
What you are looking for is to make a custom _transfer() method by overriding the one provided in the OpenZeppelin ERC20 standard.
You can check with the "OXB" (oxbull.tech) token, which implements this type of fee, but basically you just take tokens from the sender before sending them to the receiver, and once you are done charging the fees you can send the remaining tokens to the receiver.
An example would be:
function _transfer(address sender, address recipient, uint256 amount) private {
require(sender != address(0), "BEP20: transfer from the zero address");
require(balanceOf(sender) >= amount, "BEP2': not enough balance");
uint256 tokensToBurn = amount.mul(burningFee).div(100);
amount = amount.sub(tokensToBurn);
balances[sender] = balances[sender].sub(amount);
_burn(sender, tokensToBurn);
balances[recipient] = balances[recipient].add(amount);
}
Options of what you can do are infinite. Hope this is helpful.

MQTT shared subscription

With a MQTT shared subscription, the message on the subscirbed topic would only be sent to one of the subscribing clients. Then, how the other clients of the group receive the message as they also subscribe to the same topic?
With a MQTT shared subscription, the message on the subscribed topic would only be sent to one of the subscribing clients.
Correct. With a normal (non‑shared) subscription the messages are sent to ALL subscribers; with shared subscriptions they are sent to ONE subscriber.
Prior to the introduction of shared subscriptions it was difficult to handle situations where you want multiple servers (for fault tolerance, load balancing etc) but only want to process each message once. Shared subscriptions provide a simple way of accomplishing this.
Then, how the other clients of the group receive the message as they also subscribe to the same topic?
If they are subscribing to the same shared subscription (with the same ShareName) then only one will receive the message; this is by design. If you want them all to receive the message then don't use a shared subscription. Alternatively you can establish multiple subscriptions (so all subscribers receive the message but only one processes it - but note the "could") as per the spec:
If a Client has a Shared Subscription and a Non‑shared Subscription and a message matches both of them, the Client will receive a copy of the message by virtue of it having the Non‑shared Subscription. A second copy of the message will be delivered to one of the subscribers to the Shared Subscription, and this could result in a second copy being sent to this Client.
There is an interesting bug in Java Paho (1.2.5) client that prevents working with shared topics that contains wildcards (#, +) https://github.com/eclipse/paho.mqtt.java/issues/827
Long story short, this will not work:
mqttClient.subscribe("$shared/group/some_topic/#", 1, (topic, message) -> System.out.println(topic));
instead it's required to use callbacks:
mqttClient.subscribe("$shared/group/some_topic/#", 1);
mqttClient.setCallback(new MqttCallback() {
#Override
public void connectionLost(final Throwable cause) {
}
#Override
public void messageArrived(final String topic, final MqttMessage message) throws Exception {
System.out.println(topic);
}
#Override
public void deliveryComplete(final IMqttDeliveryToken token) {
}
});

Where do the ethers come from when sending ethers with .send() function in ethereum contract

I'm learning ethereum token contract following here. I'm confused by the code below:
function sell(uint amount) returns (uint revenue){
if (balanceOf[msg.sender] < amount ) throw; // checks if the sender has enough to sell
balanceOf[this] += amount; // adds the amount to owner's balance
balanceOf[msg.sender] -= amount; // subtracts the amount from seller's balance
revenue = amount * sellPrice;
if (!msg.sender.send(revenue)) { // sends ether to the seller: it's important
throw; // to do this last to prevent recursion attacks
} else {
Transfer(msg.sender, this, amount); // executes an event reflecting on the change
return revenue; // ends function and returns
}
}
the line msg.sender.send(revenue) means to send ethers to the seller. My question is:
Does the ethers to be sent come from msg.sender or from the token contract?
I think they comes from msg.sender. However the msg.sender is actually in behalf of the seller, right? That makes the seller sends himself ethers. May I know how to understand this. And then how do I make a contract send ethers back to a user account automatically?
Thanks!
I did some tests to figure out this question. I find out that the ethers which are sent to destination address are from the token contract instance address.
I was confused before because I didn't understand how a contract instance gains ethers after being constructed. Now I get to know that the contract instance gains ethers when an account invokes a method marked by keyword payable of the contract. When the invoking happens the ethers are sent to the contract address at the meantime. In the demo token code, it is the method buy() who plays the role to send ethers to the contract address.
I'm new for learning ethereum contract. There probably still are some mistakes about what I realize. Please let me know if there are. Appreciate that!
Thanks!
.send is a function belonging to the address type, where the address on which it's called is the recipient. The ETH being sent comes from the smart contract.
You can also use transfer and call. This article does a good job of explaining the differences.
Examples:
address recipient = 0x0000000000000000000000000000000000000000;
// using transfer
recipient.transfer(revenue);
// using call
recipient.call{value: revenue}("");

Communicating between (chat) server and client

just to clarify certain questions.
Let's say I'm making a chat application. Most of the online tutorials are basic server-client programs that send the chat message directly as strings.
So what if there is someone that came online, or offline. How would the client notify the server of such changes? What I came up with is to use flags {online}User, {offline}user, {privatechat}blabla.
What if someone knew how your code and that would allow them to sabotage by keep sending {online}blabla.
This would work, but has some flaws that I could think of as well. What would be the correct or better way to do this?
Can someone point me in the right direction? Thanks.
Or another example, in games. To tell the unit to move right, does it send a string back to the server {unit}{move right}? Something along those lines.
I kinda got the logic on how to make the chat server. If I just prefix a "{chat}" to the textbox. As long as I read this command "{chat}" I'll just ignore whichever commands which comes along.
How about in an RTS (not that I'm gonna make one, just curious), you mean there's literally 50 over strings telling how units move, attack, take damage, actions etc? Will all these commands be done on one thread? or multi-threaded?
Well you have to implement session-handling and send sessionToken with your order to move a unit in game. So server will be able to check whether pointed user have rights to order the pointed unit etc. Same things with chats.
In my chat, every client sends some PING message to server every two minutes. So if 5 minutes passed and no PING is received, server counts the user as [offline].
If you are afraid of cheating users who reverse engineer your client and can make serious troubles to the system with cheats, you have to do two things:
make server to check if given
user order is valid
implement bot-detection. check if
user makes some actions with some
constant time interval or if user
uses some limited amount of words in
chat etc.
I hope this post at least gives you some point.
The example of server logic is following:
[WebMethod]
string LoginUser(string login, string pwd)
{
if( dal.IsCorrectUser(login,pwd) )
{
string token = dal.MakeSession(login);
return string;
}
return "-1";
}
[WebMethod]
bool UserOrder(string token, string order)
{
if( !dal.SessionExist(token) )
{
return false;
}
int userId = dal.GetUserBySession(token);
if(! dal.ValidOrderForUser(userId,order) )
{
dal.RegisterWrongOrder(userid,order); // For cheaters-detecting purposes
return false;
}
return dal.ExecuteUserOrder(userId, order);
}
In fact you can send string or any serializable objects as an user-order.
[Serializable]
struct UserOrder
{
int unitId;
int Order;
}
All samples are for c#. Just to demonstrate logic.

Resources