Is it possible for anyone to see the data that is stored inside a private mapping in a deployed contract? And does that also apply for private variables?
Yes. Everything is visible. All you are controlling is how functions can be called.
For reference:
public: Can be called from anywhere.
private: Can be called from within the contract, but not subcontracts.
interanl: Can be called from within the contract and from subcontracts.
external: Can be called from another contract but not within the contract itself.
If the data itself needs to be private, you have to encrypt it on the client side and decrypt after retrieval (this will create problems if you need to actually use the data in a transaction), or you need to use a private blockchain.
Related
I'm trying to develop an application to track a supply chain, but due to the chain having several actors, the functionality of the main contract has extended beyond the 25kb limit.
So I'm splitting the functionality of the contract into several contracts, and I have a question about whether it is possible to access Storage type variables from other contracts. If possible, could you give me a clue, since I have not found information about it?
You can read storage properties if they have a public visibility modifier.
You can also create a corresponding setter functions. Mind that this example implementation allows anyone to set the number, so you should add an authorization mechanism so that only some senders can set the values.
// deployed on 0x123
contract A {
uint256 public number;
function setNumber(uint256 _number) external {
number = _number;
}
}
// deployed on 0x456
contract B {
function getNumberInA() external view returns (uint256) {
return A(0x123).number();
}
}
If you're open to experimental features, you can also use the Diamond pattern (EIP-2535, currently not approved yet) to make use of the common storage of the proxy contract, and implementation deployed on multiple addresses.
Looks like you want to have a Base contract and then create subcontracts. So your Base contract will access subcontracts' functions and variables. You have to implement inheritance. Let's say you have Base and Sub contracts;
// with this import you will have access to contract Name inside Sub.sol file
import "./Sub.sol"
contract Base is Sub{
// here you can just refence storage variables inside Sub.sol
// BUT storage variables inside Sub.sol has to be "public"
}
Yes, EIP2535 Diamonds solves the 24kb size limit. It does this not by accessing state variables from other contracts but by storing all state variables in one contract but utilizing code from other contracts. An into article about it is here: https://eip2535diamonds.substack.com/p/introduction-to-the-diamond-standard
EIP2535 Diamonds is beyond experimental technology. There are deployed diamonds holding millions of dollars of assets on Ethereum and Polygon. More than 30 projects are using it as this point.
Smart contracts can't access storage from each other directly. Instead, they exchange data through function calls. However, as you mentioned, there is a limit to the amount of code that can be deployed to the blockchain (24 kB).
One possible solution, suggested by Nick Mudge on EIP-2535, is to have a proxy contract called "diamond" that delegates function calls to their appropriate implementation contracts called "facets". The 24 kB size limit issue is resolved, since you can have an arbitrarily large number of facets. Furthermore, and all the facets of a diamond share the same storage context, which eliminates the need for function calls between themselves.
The specification is very robust and powerful. In particular, Cartesi has been using Diamonds to expand the functionality of smart contracts beyond the usual limit, and taking advantage of the shared storage context to reduce the gas costs of function calls. If you wish to read more about EIP-2535 and its implications on code and storage upgradability, feel free to read my article on Medium.
Thanks in advance for any help.
I have a caching service I've implemented with a core data stack in Swift 3.1. The exposed interface conforms to this protocol:
protocol WeekForecastCacheService {
func add(cacheModels: [DayForecastCacheModel])
func get(cityId: Int, callback: #escaping ([DayForecastCacheModel]?) -> () )
}
Ideally I want the internals of my core data stack to stay private.
However I also want to be able to unit test the class. Specifically the exposed interface. Because the core data stack is persistent I want to be able to delete every entity (a reset if you will to start tests in a known state). How do I go about doing this while keeping the unit test implementation outside of my main target.
Ideally I would also like my tests to be independent of implementation...
I'm thinking along the lines of the following but could do with some advice:
Add a delete all function to the cache class
Use a class extension and implement the functionality there - it would mean a fair amount of copy paste
Change private functions / variables to be internal giving enough access to easily create a delete all function in a class extension
Stop worrying because only protocols are used by classes consuming the service so it doesn't matter if functions and properties within the class are not private
When unit testing Core Data, a typical approach is to use the in-memory store type to effectively remove the "persistent" part of Core Data. With an in-memory store you get all of Core Data's usual capabilities, but the persistent store isn't written to a file so it always starts off empty. That gets you to a known starting state. If necessary you can pre-load some other known state into the in-memory store before beginning the test.
The key for this is NSInMemoryStoreType. If you're setting explicitly adding the persistent store, that would be the type value when calling addPersistentStore(ofType:configurationName:at:options:). If you're using NSPersistentContainer, you'd include the store type in the persistentStoreDescriptions property.
I was trying to implement a grails SearchService that indexes certain text and stores it in memory for faster lookup. In order to store this data, I was trying to use a private static property in the Service to store the data, but the property was randomly resetting values. After rereading documentation, I realized that this is likely because grails services are supposed to be stateless since the employee the singleton pattern. Still, not sure I understand how a static variable can vary. Does the JVM load separate copies of service classes per thread? Not sure I'm wrapping my head around what's happening.
Nonetheless, now that I know I can't rely on static variables to store application-wide data, what's the best approach to store and access data for use across the application, while keeping synchronization and avoiding races?
Caused by: java.lang.IllegalStateException: Method on class [TEXTSTORE] was used outside of a Grails application. If running in the context of a test using the mocking API or bootstrap Grails correctly.
at SearchService.buildIndex(SearchService.groovy:63)
at SearchService$_indexAllDomains_closure2.doCall(SearchService.groovy:42)
at SearchService.indexAllDomains(SearchService.groovy:41)
at SearchService.$tt__rebuildIndex(SearchService.groovy:48)
at SearchService.afterPropertiesSet(SearchService.groovy:35)
... 4 more
You seem to be a bit confused about services in Grails. There is no reason why a service (defaulting to singleton) can't have shared state. It's not uncommon for a service to populate some cached or indexed data when it is created so it can be used by multiple callers.
Most often this is done by implementing the org.springframework.beans.factory.InitializingBean interface and making use of the afterPropertiesSet() method which is called when the service (Spring bean) has been created in the application context and all dependencies have been resolved.
For example:
package com.example
import org.springframework.beans.factory.InitializingBean
class MyExampleService implements InitializingBean {
private List data
def otherService
void afterPropertiesSet() {
data = otherService.doSomethingToFetchData()
}
// .. other stuff
}
By hooking into the lifecycle of the bean you can be fairly sure that even in development (when your service reloads because you've changed some code) it will still have the data needed.
Private is a access specifier. It means that anything say a instance private declared private cannot be accessed by methods of another class.
What is the point of being private if it can be changed by public methods.
Maybe it is because either because my book's poor explanation or my understanding problem that I just don't get what private is.
The book says that being private is a process of hiding the data and providing methods for data access. (Encapsulation)
Also, here is a example where a error would occur. But I have no idea what is it:
public class BankRobber
{
BandAccount momSavings =
new BankAccount (1000);
...
momSaving.balance = -1000;
}}
A
The point of "private" is not to make it impossible for other classes to access the member, but to make it impossible for other classes to access the member except in ways that are allowed by the public (or protected) methods.
I have a service that interacts with a brokerage account's API. It works fine, but now I need to interact with two different accounts at the same brokerage.
It seems like the best way to handle this is to make it possible to configure the service to specify the target account and then instantiate two different instances, one for each account.
I'm not sure if this is supported in Grails or how to go about it.
Two questions:
Is there a better way to do this?
If not, how can I instantiate and configure two different service instances?
ADDITIONAL INFORMATION:
Both answers are near misses. Let me try to clarify:
I didn't want to get into the details, but it may help to explain what I'm after. I'm using the Interactive Brokers trading API, and they don't let you talk directly to their servers the way other brokerages do. You have to talk over a socket to their IB Gateway, which is a piece of software they provide that essentially proxies their servers. So your app talks to IB Gateway, and IB Gateway talks to Interactive Brokers' servers on your app's behalf.
The catch is that IB Gateway has to be logged in to an account as part of its configuration. So, in order to trade two different accounts, you have no choice but to configure two different IB Gateways, since each can only access the account that it is configured for.
So my Grails code for placing trades must select the right IB Gateway to talk to. That means it needs to know the IP address and port of the IB Gateway that corresponds to each account. Other than this setting for IP address and port, there is no difference between the two Grails services that communicate with IB Gateway.
What I want is to reuse the same service class, each being instantiated as a singleton, simply having a different IP address and port on which to communicate.
So making two different services is undesirable, since the code is otherwise identical. (And if I add a third or fourth IB Gateway, this becomes fairly smelly code.)
And this setting should exist for the life of the application, so I don't think a change in scope is really the answer, either.
I really want two instances of the same service, simply having different configurations.
I hope that helps explain the situation. What do you suggest? Thank you!
If the same business logic is applicable for both accounts but taking into consideration that you cannot have a single service class talking to the API for both accounts, then yes you can have 2 service classes (which are nothing but 2 different spring beans) with the default singleton scope.
class Account1Service{
}
class Account2Service{
}
I would also try if I can use inheritance here in this case, if I have common logic that can be shared across. But keep in mind, if you are inheriting a service class from an abstract class then the abstract class has to be placed in src/groovy that is, outside /grails-app/ to defy Dependency Injection. In that case you might end up with (untested, but you can adhere to DRY concept)
// src/groovy
abstract class BrokerageService {
def populateAccountDetails(Long accountId)
def checkAccountStatus(Long accountId)
}
//grails-app/services
class Account1Service extends BrokerageService {
//Implement methods + add logic particular to Account1
//By default transacitonal
}
class Account2Service extends BrokerageService {
//Implement methods + add logic particular to Account2
//By default transacitonal
}
Also keep a note that the scope is singleton, you would take extra care (better avoid) maintaining global scoped properties in Service class. Try to make as stateless as possible. Unless otherwise the situation or the business logic demands to use service level scopes like session, flow or request, I would always stick to the default singleton scope.
To answer your second question, you do not need to instantiate any of the grails service class. The container injects appropriate service class (using Spring IoC) when an appropriate nomenclature is used. In the above example, the service classes will automatically be injected if you follow this naming convention in classes where you wan tto use the services:
//camelCase lower initial
def account1Service
def account2Service
UPDATE
This is in response to the additional information provided by OP.
Referring to the above scenario, there can be only one service class in the default singleton scope to handle things perfectly. The best part, since you are going out of your network and not really worried about own database transactions the service class can be set to non-transactional. But again it depends on the situations need. Here is how the service class would look like.
//grails-app/service
class BrokerageService{
//Service method to be called from controller or any endpoint
def callServiceMethod(Long accountId){
.......
doSomethingCommonToAllAccounts()
.........
def _ibConfig = [:] << lookupIBGatewayConfigForAccount(accountId)
........
//Configure an IB Gateway according to the credentials
//Call IB Gateway for Account using data got from _ibConfig map
//Call goes here
}
def doSomethingCommonToAllAccounts(){
........
........
}
def lookupIBGatewayConfigForAccount(accountId){
def configMap = [:]
//Here lookup the required IP, account credentials for the provided account
//If required lookup from database, if you think the list of accounts would grow
//For example, if account is JPMorgan, get credentials related to JPMorgan
//put everything in map
configMap << [ip: "xxx.xx.xx.xxx", port: 80, userName: "Dummy"] //etc
return configMap
}
}
The scope of the service class is singleton which means there will be only one instance of the class in the heap, which also means that any class level property (other than methods) will be stateful. In this case, you only deal with methods which will be stateless and would suffice the purpose. You would get what you need without spending heap or without creating new instances of BrokerageService every time a trading happens.
Each trade (with an account assciated) will eventually call the service, lookup the credentials from db (or config properties, or flat files, or properties files) and subsequently configure the IB Gateway and call/talk to the gateway.
Grails services are supposed to be singletons by default, not having any state associated to what it is doing and usually only one instance. Namely, you wouldn't have instance fields in them, normally.
But if you override the default scope, you can have them. For example, you can make your service to be session scoped, adding this static variable:
static scope = "session"
Then you'll have one instance for each user session.
For your particular case, you may want to take a look at the prototype scope, which will give you a new instance of the service each time you need it injected. You just will have to make sure to always use that instance after it is injected, if you want them to act on the same data.
Take a look at the docs about Scoped Services.