Update gsn_advanced.adoc (#1884)

* Update gsn_advanced.adoc

Line 15 - where it says, "prevent malicious users from spending the transactions subsidy", with transactions subsidy, is it supposed to be possessive "transaction's subsidy" or is the plural in the wrong place "transaction subsidies"?

Line 176 - where it says "or it is not allowed to spend that amount". Is IT referring to the sender/person or the tx? If IT refers to a person, then change to "or they are not allowed..." for gender neutral.

Line 213 - Where it says, "Please not how the gas cost estimation", a verb is missing, please what?

* Update gsn_advanced.adoc

Apply suggestions by Amy
pull/1886/head
amystrayer 6 years ago committed by Santiago Palladino
parent f2c3af4d0f
commit 2b3aa0d220
  1. 40
      docs/modules/ROOT/pages/gsn_advanced.adoc

@ -2,7 +2,7 @@
This guide shows you different strategies (Bouncers) to accept transactions via Gas Station Network.
First, we will explain the Bouncer concept and then we will showcase how to use the two most common strategies.
First, we will explain the Bouncer concept, and then we will showcase how to use the two most common strategies.
Finally, we will cover how to create your own custom Bouncer.
@ -10,7 +10,7 @@ If you're still learning about the basics of the Gas Station Network, you should
== GSN Bouncers
A *GSN Bouncer* decides which transaction gets approved and which transaction gets rejected. Bouncers are a key concept within GSN. Dapps need Bouncers to prevent malicious users to spend the transactions subsidy.
A *GSN Bouncer* decides which transaction gets approved and which transaction gets rejected. Bouncers are a key concept within GSN. Dapps need Bouncers to prevent malicious users from spending the subsidies for the transactions.
As we have seen in the Basic Guide, in order to use GSN, your contracts need to extend from GSN Recipient.
@ -24,7 +24,7 @@ The first can be done via the https://gsn.openzeppelin.com/recipients[GSN Tools]
The sender and data can be used safely when using `GSNRecipient` and _msgSender & _msgData.
The third is a bit more complex. The GSN Recipient, by default, will accept and pay for all transactions. Chances are you probably want to choose which users can use your contracts via the GSN, and potentially charge them for it, like a bouncer at a nightclub. We call these contracts _GSNBouncers_.
The third is a bit more complex. The GSN Recipient, by default, will accept and pay for all transactions. Chances are you probably want to choose which users can use your contracts via the GSN and potentially charge them for it, like a bouncer at a nightclub. We call these contracts _GSNBouncers_.
We include two of them below, ready to use out of the box.
@ -34,20 +34,20 @@ This bouncer lets users call into your recipient contract via the GSN (charging
The signature used to create the transaction must be added to the contract as a trusted signer. If it is not the same, this bouncer will not accept the transaction.
This means that you need to set up a system where your trusted account signs call requests, if they are valid users.
This means that you need to set up a system where your trusted account signs call requests, as long as they are valid users.
The definition of a valid user depends on your system but an example is users that have completed their sign up via some kind of oauth and validation e.g. gone through a captcha, or validated their email address.
You could restrict it further and let new users send a specific number of transactions (e.g. 5 requests via the GSN, at which point they need to create a wallet).
Alternatively, you could charge them off-chain (e.g. via credit card) for credit on your system, and let them run GSN calls until said credit runs out.
The definition of a valid user depends on your system, but an example is users that have completed their sign up via some kind of oauth and validation, e.g., gone through a captcha or validated their email address.
You could restrict it further and let new users send a specific number of transactions (e.g., 5 requests via the GSN, at which point they need to create a wallet).
Alternatively, you could charge them off-chain (e.g., via credit card) for credit on your system and let them run GSN calls until said credit runs out.
The great thing about this setup is that *your contract doesn't need to change*. All you're doing is changing the backend logic conditions under which users call into your contract for free.
On the other hand, you need to have a backend server, microservice or lambda function to accomplish this.
On the other hand, you need to have a backend server, microservice, or lambda function to accomplish this.
=== How does it work?
Here is the definition of acceptRelayedCall function.
It decides whether or not accept the call based on the signature. No further gsn-actions need to be taken.
It decides whether or not to accept the call based on the signature. No further gsn-actions need to be taken.
It only relies on the approvalData and does not use callData.
@ -118,7 +118,7 @@ On the other hand, when the signatures don't match, the call gets rejected with
----
=== How to use it?
=== How to use it
Create your contract using the following:
@ -131,14 +131,14 @@ Create your contract using the following:
== GSNBouncerERC20Fee
This bouncer is a bit more complex (but don't worry we've already wrote it for you!). Unlike `GSNBouncerSignature`, this Bouncer doesn't require any off-chain services.
This bouncer is a bit more complex (but don't worry, we've already written it for you!). Unlike `GSNBouncerSignature`, this Bouncer doesn't require any off-chain services.
Instead of manually approving each transaction, you will give tokens to your users. These tokens are then used to pay for GSN calls to your recipient contract.
Any user that has enough tokens is automatically approved and the recipient contract will cover his transaction costs!
This bouncer charges users for the ether cost your recipient will incur. Each recipient contract has their own unique token, with a baked-in exchange rate of 1:1 to ether, since they act as an ether replacement when using the GSN.
The recipient has an internal mint function. Firstly, you need to setup a way to call it (e.g. add a public function with onlyOwner or some other form of access control).
Then issue tokens to users based on your business logic. For example, you could mint limited tokens to new users, mint tokens when they buy them off-chain, give tokens based on the user subscription etc.
The recipient has an internal mint function. Firstly, you need to setup a way to call it (e.g., add a public function with onlyOwner or some other form of access control).
Then, issue tokens to users based on your business logic. For example, you could mint limited tokens to new users, mint tokens when they buy them off-chain, give tokens based on the user subscription, etc.
NOTE: *Users do not need call approve* on their tokens for your recipient to use them. They are a modified ERC20 variant that lets the recipient contract retrieve them.
@ -173,10 +173,10 @@ function acceptRelayedCall(
}
----
The bouncer rejects the tx if the real sender doesn't have enough tokens or it is not allowed to spend that amount.
If the sender can spend the tokens, the bouncers approves the transaction and overrides _confirmRelayedCall to make that data available to pre and post.
The bouncer rejects the tx if the real sender doesn't have enough tokens or they are not allowed to spend that amount.
If the sender can spend the tokens, the bouncers approve the transaction and overrides _confirmRelayedCall to make that data available to pre and post.
Let's see now how we perform the token transfer inside the _preRelayedCall method.
Now, let's see how we perform the token transfer inside the _preRelayedCall method.
[source,solidity]
----
@ -189,7 +189,7 @@ function _preRelayedCall(bytes memory context) internal returns (bytes32) {
----
We transfer the max amount of tokens assuming that the call will use all the gas available.
Then in the _postRelayedCall method we calculate the actual amount - including the implementation and ERC transfers - and refund the difference.
Then, in the _postRelayedCall method, we calculate the actual amount - including the implementation and ERC transfers - and refund the difference.
[source,solidity]
----
@ -210,11 +210,11 @@ function _postRelayedCall(bytes memory context, bool, uint256 actualCharge, byte
This is required to protect the contract from exploits (this is really similar to how ether is locked in Ethereum transactions).
Please not how the gas cost estimation is not 100% accurate, we may tweak it further down the road.
Please note how the gas cost estimation is not 100% accurate, we may tweak it further down the road.
NOTE: `_preRelayedCall` and `_postRelayedCall` are used instead of preRelayedCall and postRelayedCall. This prevents them from being called by non-relayhub. Always use _pre and _post methods.
=== How to use it?
=== How to use it
Create your contract using the following:
@ -233,6 +233,6 @@ Create your contract using the following:
You can use 'GSNBouncerBase' as an example to guide your Bouncer implementation.
The only thing you must do is to extend from `GSNRecipient` and implement the accept method.
The only thing you must do is extend from `GSNRecipient` and implement the accept method.
Depending on your logic, you may need to implement `_postRelayedCall` and `_preRelayedCall`.

Loading…
Cancel
Save